Topics

How to Share Private Astro Components Without npm

  • column

Sharing and Managing Components

In web development, there are occasionally cases where you want to reuse the same UI components across multiple websites, right?

When developing multiple sites efficiently with a modern framework like Astro, sharing a component library is very effective. However, if you share components as npm packages, you will need to pay for a paid plan to publish private packages, right?

In this article, we introduce how to share and manage components efficiently using a GitHub repository and Cloudflare Pages, without packaging them with npm!

What Are the Challenges of Sharing Components?!

  • Want to use the same UI components across multiple Astro sites!
  • Want to host on Cloudflare Pages!
  • I want to manage components in a private GitHub repository!
  • I want to package the components as an npm package, but I don't want to make them public!

That's the situation. So, what's the best way to handle it?

Solve it with a GitHub repository and a custom build script

To address these challenges, here's an approach you might consider.

  1. Create a GitHub repository for the components
  2. Use file references for local development
  3. In the Cloudflare Pages environment, clone the component repository at build time

Components can be shared and managed without using a private npm package.

Implementation overview

1. Create a GitHub Personal Access Token

Create a GitHub Personal Access Token to access private repositories.

  1. Log in to GitHub
  2. Click your profile icon in the upper-right corner → Settings
  3. In the left sidebar, select "Developer settings" → "Personal access tokens" → "Tokens (classic)"
  4. Click "Generate new token" → "Generate new token (classic)"
  5. Grant the token the following permission:
    • repo - Full access to private repositories
  6. Generate the token and store it in a secure location (it is displayed only once).

2. Build the component library

Create a GitHub repository for your components (e.g., github.com/your-username/ui-components).

The package.json of the component library

{
  "name": "@your-org/components",
  "private": true,
  "type": "module",
  "main": "src/index.ts",
  "exports": {
    ".": "./src/index.ts"
  },
  "files": [
    "src"
  ],
  "peerDependencies": {
    "astro": "^5.7.12"
  }
}

3. Set Up the Main Project

Configure the package.json of the main project that will use the components.

The package.json of the main project

{
  "name": "your-astro-project",
  "type": "module",
  "private": true,
  "config": {
    "componentVersion": "v1.0.0",
    "orgName": "your-username",
    "repoName": "ui-components",
    "namespace": "your-org",
    "packageName": "components"
  },
  "scripts": {
    "dev": "astro dev",
    "start": "astro dev",
    "build": "astro build",
    "preview": "astro preview",
    "astro": "astro",
    "setup-components": "set -e; ORG_NAME=\\\\"$npm_package_config_orgName\\\\"; REPO_NAME=\\\\"$npm_package_config_repoName\\\\"; NAMESPACE=\\\\"$npm_package_config_namespace\\\\"; PACKAGE_NAME=\\\\"$npm_package_config_packageName\\\\"; VERSION=\\\\"$npm_package_config_componentVersion\\\\"; mkdir -p temp; git clone -b $VERSION <https://[email protected]/$ORG_NAME/$REPO_NAME.git> temp/$REPO_NAME; mkdir -p node_modules/@$NAMESPACE; ln -sf $(pwd)/temp/$REPO_NAME node_modules/@$NAMESPACE/$PACKAGE_NAME",
    "build-with-components": "npm run setup-components && npm run build"
  },
  "dependencies": {
    "@your-org/components": "file:../ui-components"
  },
  "devDependencies": {
    // Astroなどの開発依存関係
  }
}

There are four key points to keep in mind.

  1. config section: Centrally manages the component library's information
  2. setup-components script: Clones the components from GitHub at build time
  3. build-with-components script: A combined command that sets up the components and runs the build
  4. dependencies: File references for local development

4. Set up the local development environment

Clone the component library into the same directory as your project and reference it using file paths.

projects/
  ├── ui-components/         # コンポーネントライブラリ
  └── your-astro-project/     # メインプロジェクト

Changes you make to components during local development are immediately reflected in the main project.

5. Configure Cloudflare Pages

Here is how to configure Cloudflare Pages.

  1. Setting environment variables:
    • Pages dashboard → your-project → Settings → Environment variables
    • Variable name: GITHUB_TOKEN
    • Value: The GitHub Personal Access Token you created
  2. Configuring the build command:
    • Pages dashboard → your-project → Settings → Build & deployments
    • Build command: npm run build-with-components
    • Build output directory: dist (default)

During the build, the component library at the specified version is automatically cloned and incorporated.

Easy component usage once setup is complete

Once setup is complete, using the components is very simple.

Create src/index.ts in the component library and export the components.

export { default as Button } from './components/base/Button.astro';
export { default as Heading } from './components/base/Heading.astro';
// 他のコンポーネントもここでエクスポート

In the main project, import the components you want to use.

---
import { Button, Heading } from '@your-org/components';
---

<div>
  <Heading>Hello World</Heading>
  <Button>Click me</Button>
</div>

How is version control handled?

When you want to release a new version of the component library,

  1. Make changes to the component library and commit them
  2. Create a new tag (e.g., v1.1.0)
  3. Update the package.json in the main project
    "config": {
      "componentVersion": "v1.1.0",
      // 他の設定...
    }
    
    

Each project can use the component version it needs.

A safe development flow too

A safe and efficient development flow means fewer things to worry about, which is a real relief.

  1. Develop and modify new features in the component library (e.g., feature/new-button branch)
  2. Immediately test and verify those changes in the main project in your local environment
  3. Once development reaches a certain stage, create a tag for testing (e.g., v1.1.0-test)
  4. In the main project's test environment branch, update componentVersion to the test tag and deploy to the test environment
  5. Once you've confirmed everything works in the test environment, merge into the main branch of the component library
  6. It goes live by creating a new version tag and updating the version in the main project (e.g., v1.1.0).

The key point is that you can test component changes without affecting the production environment!

The production environment on Cloudflare Pages uses the version of the tag specified in config.componentVersion, so you can rest assured that changes won't affect production unless you create a new tag and update the config.

■ Share components across a GitHub private repository and a custom build script, without using npm private packages!

■ With proper management of GitHub tokens and correct local development environment setup, components can be shared seamlessly across the entire team!

How does that sound?

Wouldn't this be a great fit for small to mid-sized teams and projects that prioritize cost efficiency?

As your team or project grows, you may consider moving to npm private packages, but for now, I believe this approach enables efficient component sharing!


Note: This approach also works with frameworks other than Astro (such as React, Vue, and Svelte). Configuration details may differ, but the basic approach is the same! You can also customize the build process in the same way on hosting services other than Cloudflare Pages.

About the author

Starting out in DTP and moving into the web, he now handles markup, frontend, direction, and accessibility alike. A "master of all trades" who has been versatile since Liberogic's early days and is now a walking encyclopedia of the company. Lately he has been hooked on exploring efficiency through prompts, asking, "Can't we rely more on AI for accessibility work?" Both his skills and his thinking are still evolving.

Ayumu Futamata

IAAP Certified Web Accessibility Specialist (WAS) / Markup Engineer / Frontend Engineer / Web Director

View this staff member's articles

Reliable team structure and responsive support are our strengths

Liberogic's experienced staff actively drive projects forward, which has earned high praise from our clients.
We make sure to properly assign project managers and directors to keep the entire project running smoothly. Our style of allocating resources to the right people, rather than adding full-time commitment unnecessarily, helps prevent cost increases. We are also known for our speed, from understanding the scope of work to preparing and submitting estimates.

Note: Please be advised that we do not actively engage in SES-style on-site staffing assignments.

We support nearly all major project management and chat tools, including Slack, Teams, Redmine, Backlog, Asana, Jira, Notion, Google Workspace, Zoom, and Webex.

Are you struggling with technical challenges or how to approach large-scale projects that involve SES or offshore teams?

Case Studies