A modern Vite-based module builder template with automated publishing to both GitHub Pages (for demos) and NPM (for distribution).
- π¦ Output: ES, CommonJS, and UMD formats
- π§ͺ Demo page with Tailwind CSS
- π Automated workflows: NPM release + GitHub Pages deploy
- βοΈ Built-in project setup script
- π§ Written in TypeScript
- Vite Module Builder Template
This repo is a starter workflow for building and publishing JavaScript modules with Vite. It:
- Supports ESM, CommonJS, and UMD outputs
- Includes a demo page with Tailwind CSS (not bundled in the module)
- Automates publishing with GitHub Actions
- Uses a simple setup script to personalize the template
Great for creating standalone libraries, custom elements, or utility modules.
Click "Use this template" on the GitHub repo homepage to create a new repo under your GitHub account.
Once cloned and downloaded to your development machine, run the setup script:
npm run project-setup
You'll be prompted for:
- The module name (e.g.,
my-module-name
) - The GitHub Pages base URL (e.g.,
https://<USERNAME>.gitHub.io/<REPO>/
)
This updates filenames, package.json
, and vite.demo.config.js
. It also runs
npm install
.
You will see a reminder to turn off your GitHub actions at this point. You can re-enable them when you are ready.
Run the dev server:
npm run dev
The general workflow is that you'll have a basic HTML page that includes your module. You'll work on the module itself in the lib
directory.
Here is a overview of the files and locations.
- Work on your module in
lib/your-module.ts
file. - Your demo site's HTML and assets are in the
demo
directory. - Demo script logic lives in
demo/assets/demo.ts
- Note of how the library you're working on is included in the
demo.ts
file,../../lib/
- Your demo site will be available at
http://localhost:8888/
and will has hot module replacement so you can see your changes as you make them.
When you are happy with a basic initial version, commit your changes to your local git repo:
git add .
git commit -m "Initial commit"
Before we push to GitHub, we need to set up the repo for GitHub Pages and NPM publishing.
I recommend publishing your initial version to NPM as an alpha version from your local repo. This way, you can test the publishing process and make sure everything works as expected. After you've published at least one, you can also generate a token on the NPM website that is specific to your package. If the package has not been published yet, you will not be able to generate a token specific to the package.
Let's go over this step-by-step.
First, update your package.json
file to include the following publishConfig
section:
"publishConfig": {
"access": "public",
"tag": "alpha"
},
Also in the package.json
, update the version number to something like
1.0.0-alpha.0
. You should also confirm that you have the correct name
that you intend to publish your module under. For example, I add @morton-studio/
before the name of my module to have it published under my organization name.
Next, build a local version of your package using the following command:
npm run build
This will create a dist
folder on your local machine with the built files. The
files in the dist
folder are what will be published to NPM. The files in this
directory are excluded from the GitHub repo, so you will not add them to the
repo.
I will assume you have already set up your NPM account. Next, log in to NPM from the command line. If you have not done this before, run the following command:
npm login
Once you are logged in, you can publish your package to NPM using the following command:
npm publish
This will publish your package to NPM with the alpha
tag.
Visit the homepage of your module on NPM to confirm that you see it published.
In your GitHub repo, you will need a Access Token from your NPM repository that will
allow you to publish new versions of your module on your behalf. This will be stored in your GitHub secrets for the repo.
In the .gitHub/workflows/npm-publish.yml
file, you will need a reference to it,
secrets.NPM_TOKEN
. If you choose a different name for your secret, you will
need to update the workflow file.
For added security, I suggest creating a Granular Access Token for publishing to only this package. The token will need Read and write access.
In the repo's settings, you will need to add the secret to the repo. You can do
this by going to the repo's settings, then to the "Secrets and variables"
section and then select the "Actions" section. Click the "New repository secret"
button and add the secret as shown below. Use the name NPM_TOKEN
unless you've changed it in your workflow file.
If you don't want to publish your demo page to GitHub Pages or your module to NPM, you can disable the workflows.
I do this early in development to prevent these processes from running before I'm ready. You can do this by going to the repo's settings, then to the "Actions" section. Click the "Disable Actions" button as shown below.
You can re-enable the workflows by clicking the "Enable Actions" button on this same screen when you are ready.
Now that the initial setup is complete, let's run through the build process and publishing to NPM.
The build generates the following outputs by default:
Format | Type | Syntax | Target |
---|---|---|---|
es |
ESM | import |
Modern browsers, bundlers |
cjs |
CommonJS | require |
Node.js |
umd |
UMD | Global | Script tag/CDNs |
You can control output formats via vite.config.js
. Only want ESM?
formats: ['es']
If you change the output formats, you will need to update the package.json
file to include the new formats. The main
and module
fields in the
package.json
file should point to the correct files for each format.
You can test the package without publishing:
npm run build
npm pack --dry-run
The publishing process has evolved from version 1.0 to 2.0 for a more intentional release workflow. Previously, updating the version in package.json and pushing to GitHub automatically triggered an NPM release. Now, version 2.0 introduces a more deliberate process with tagging.
This section is a brief overview of the tagging process in Git and NPM.
Tag exists in both Git and NPM contexts, but they serve different purposes. Let's breakdown clarify the distinction and explain their roles.
In Git, a tag is a reference to a specific commit in the repository's history. Git tags are often used to mark important points in the project, such as releases or milestones. They are immutable and serve as a snapshot of the code at that point in time.
In NPM, a tag is a label that can be assigned to a specific version of a
package. Tags are used to manage different versions of a package and control
which version is installed when users run npm install <package-name>
. The most
common tag is "latest," which indicates the most recent stable version of the
package. When you publish a package to NPM, you can assign it a tag. By default,
the latest version is tagged as "latest." However, you can also create custom
tags (e.g., "beta," "alpha") to indicate pre-release versions or specific stages
of development.
Versioning is a crucial part of the release process. It helps you keep track of changes and ensures that users can easily identify which version they are using. Let's look at a few examples of versioning your module.
Update the package.json
file for a normal (i.e. "latest") release:
"version": "1.2.3",
"publishConfig": {
"access": "public",
"tag": "latest"
}
For prereleases:
"version": "1.2.3-beta.1",
"publishConfig": {
"tag": "beta"
}
After you've updated the code in your module and have updated your
package.json
file, you are ready to publish your module to NPM.
If you have disabled your GitHub Actions, turn them back on now.
Note that we precede the version number with a v
in the tag name. This is a
convention that is used by GitHub to identify tags. The version number should be
the same as the version number in your package.json
file. The v
also
triggers the GitHub Action to publish the module to NPM.
The process is as follows:
-
Commit changes and push them to GitHub:
git add . git commit -m "Prepare release v1.2.3" git push origin main
-
Tag the release and push the tag to GitHub:
git tag v1.2.3 git push origin v1.2.3
Pushing the tag to GitHub triggers the GitHub Action to publish to NPM.
- Triggered by a Git tag starting with
v
- Requires
NPM_TOKEN
secret in GitHub repo
- Triggered on
main
branch updates β οΈ Must configure GitHub Pages to use GitHub Actions
In early dev, you can disable actions from repo settings β Actions.
File | Purpose |
---|---|
lib/your-module.ts |
Main module source file |
index.html |
Demo/testing UI |
demo-page-assets/demo.ts |
Script for demo logic |
public/ |
Static assets |
vite.config.js |
Build config (for publishing) |
vite.demo.config.js |
Dev/demo config |
.gitHub/workflows/ghpages.yml |
Deploys demo to GitHub Pages |
.gitHub/workflows/npm-publish.yml |
Publishes package to NPM |
Live demo page: https://johnfmorton.github.io/vite-module-builder-w-ghpages-npm-template/
Real-world example: https://github.com/johnfmorton/progressive-share-button
Feedback and contributions are welcome! If you find this template useful, consider giving it a star on GitHub. Happy coding!