Publish to NPM

Building a new Astro component? Publish it to npm!

Publishing an Astro component is a great way to reuse your existing work across your projects, and to share with the wider Astro community at large. Astro components can be published directly to and installed from NPM, just like any other JavaScript package.

Looking for inspiration? Check out some of our favorite themes and components from the Astro community. You can also search npm to see the entire public catalog.

Don’t want to go it alone? Check out Astro Community’s component template for a community-supported, out-of-the-box template!

To get started developing your component quickly, we have a template already setup for you.

# Initialize the Astro Component template in a new directory
npm create astro@latest my-new-component-directory -- --template component
# yarn
yarn create astro my-new-component-directory --template component
# pnpm
pnpm create astro@latest my-new-component-directory -- --template component

Before diving in, it will help to have a basic understanding of:

To create a new package we strongly recommend configuring your development enviroment to use workspaces within your project. This will allow you to develop your component alongside a working copy of Astro.

├─ demo/
| └─ ... for testing and demonstration
├─ package.json
└─ packages/
  └─ my-component/
      ├─ index.js
      ├─ package.json
      └─ ... additional files used by the package

In this example, named my-project, we create a project with a single package, named my-component, and a demo/ directory for testing and demonstrating the component.

This is configured in the project root’s package.json file.

  "name": "my-project",
  "workspaces": ["demo", "packages/*"]

In this example, multiple packages can be developed together from the packages directory. These packages can also be referenced from demo, where you can install a working copy of Astro.

npm create astro@latest demo -- --template minimal
# yarn
yarn create astro my-new-component-directory --template minimal
# pnpm
pnpm create astro@latest my-new-component-directory -- --template minimal

There are two initial files that will make up your individual package: package.json and index.js.

The package.json in the package directory includes all of the information related to your package, including its description, dependencies, and any other package metadata.

  "name": "my-component",
  "description": "Component description",
  "version": "1.0.0",
  "homepage": "",
  "type": "module",
  "exports": {
    ".": "./index.js",
    "./astro": "./MyAstroComponent.astro",
    "./react": "./MyReactComponent.jsx"
  "files": ["index.js", "MyAstroComponent.astro", "MyReactComponent.jsx"],
  "keywords": ["astro","astro-component", "...", "..."]

A short description of your component used to help others know what it does.

  "description": "An Astro Element Generator"

The module format used by Node.js and Astro to interpret your index.js files.

  "type": "module"

We recommend using "type": "module" so that your index.js can be used as an entrypoint with import and export.

The url to the project homepage.

  "homepage": ""

This is a great way to direct users to an online demo, documentation, or homepage for your project.

The entry points of a package when imported by name.

  "exports": {
    ".": "./index.js",
    "./astro": "./MyAstroComponent.astro",
    "./react": "./MyReactComponent.jsx"

In this example, importing my-component would use index.js, while importing my-component/astro or my-component/react would use MyAstroComponent.astro or MyReactComponent.jsx respectively.

This is an optional optimization to exclude unnecessary files from the bundle shipped to users via npm. Note that only files listed here will be included in your package, so if you add or change files necessary for your package to work, you must update this list accordingly.

  "files": ["index.js", "MyAstroComponent.astro", "MyReactComponent.jsx"]

An array of keywords relevant to your component that are used to help others find your component on npm and in any other search catalogs.

We recommend adding astro-component as a special keyword to maximize its discoverability in the Astro ecosystem.

  "keywords": ["astro-component", "... etc", "... etc"]

Keywords are also used by our integrations library! See below for a full list of keywords we look for in NPM.

The main package entrypoint used whenever your package is imported.

export { default as MyAstroComponent } from './MyAstroComponent.astro';

export { default as MyReactComponent } from './MyReactComponent.jsx';

This allows you to package multiple components together into a single interface.

import { MyAstroComponent } from 'my-component';
import { MyReactComponent } from 'my-component';
<MyAstroComponent />
<MyReactComponent />

Example: Using Namespace Imports

Section titled Example: Using Namespace Imports
import * as Example from 'example-astro-component';
<Example.MyAstroComponent />
<Example.MyReactComponent />

Example: Using Individual Imports

Section titled Example: Using Individual Imports
import MyAstroComponent from 'example-astro-component/astro';
import MyReactComponent from 'example-astro-component/react';
<MyAstroComponent />
<MyReactComponent />

Astro does not have a dedicated “package mode” for development. Instead, you should use a demo project to develop and test your package inside of your project. This can be a private website only used for development, or a public demo/documentation website for your package.

If you are extracting components from an existing project, you can even continue to use that project to develop your now-extracted components.

Astro does not currently ship a test runner. This is something that we would like to tackle. (If you are interested in helping out, join us on Discord!)

In the meantime, our current recommendation for testing is:

  1. Add a test fixtures directory to your demo/src/pages directory.
  2. Add a new page for every test that you’d like to run.
  3. Each page should include some different component usage that you’d like to test.
  4. Run astro build to build your fixtures, then compare the output of the dist/__fixtures__/ directory to what you expected.
  ├─ test-name-01.astro
  ├─ test-name-02.astro
  └─ test-name-03.astro

Once you have your package ready, you can publish it to npm!

To publish a package to npm, use the npm publish command. If that fails, make sure that you have logged in via npm login and that your package.json is correct. If it succeeds, you’re done!

Notice that there was no build step for Astro packages. Any file type that Astro supports can be published directly without a build step, because we know that Astro already supports them natively. This includes all files with extensions like .astro, .ts, .jsx, and .css.

If you need some other file type that isn’t natively supported by Astro, you are welcome to add a build step to your package. This advanced exercise is left up to you.

Share your hard work by adding your integration to our integrations library!

The library is automatically updated nightly, pulling in every package published to NPM with the astro-component keyword.

The integrations library reads the name, description, repository, and homepage data from your package.json.

Avatars are a great way to highlight your brand in the library! Once your package is published you can file a GitHub issue with your avatar attached and we will add it to your listing.

Need to override the information our library reads from NPM? No problem! File an issue with the updated information and we’ll make sure the custom name, description, or homepage is used instead.

In addition to the required astro-component keyword, special keywords are also used to automatically organize packages. Including any of the keywords below will add your integration to the collection in our integrations library.

collection keywords
All astro-component
Analytics analytics
CMS cms, database
CSS + UI css, ui, icon, icons, renderer
E-commerce ecommerce, e-commerce
Performance performance, perf
SEO seo, performance, perf

We encourage you to share your work, and we really do love seeing what our talented Astronauts create. Come and share what you create with us in our Discord or mention @astrodotbuild in a Tweet!