Jetpack: Rspack with the configuration already filled in
Run and build web code with Rspack.
At a glance
- What is it?
- Jetpack is a preconfigured Rspack setup for web projects, where one command starts a dev server and one builds production assets, with a config file only if the defaults do not fit. It suits a developer who wants a working build in a new project without writing bundler configuration, and the trade is that it is a curated opinion rather than a blank canvas.
- Who is it for?
- Jetpack fits a developer starting a web project who wants a sensible Rspack configuration on the first run, since the defaults cover TypeScript, JSX, CSS and SCSS, polyfills, minification and content hashing without you writing any of it.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 26 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two commands and a config file you may never write
Jetpack is preconfigured Rspack for web code, and the description is the pitch: one command to start a dev server, one command to build production assets, and a config file only when you need it.
The whole onboarding is three lines:
npm install -g jetpack
jetpack
jetpack buildJetpack requires Node 20 or newer and is published as ESM.
That is a small thing to look at, but the shape of it is the point. The zero-configuration claim in the repository topics is not about a bundler with no configuration, it is about a bundler whose configuration is already written. Any bundler configuration is a set of decisions you have to make or copy.
Jetpack makes those decisions once, ships them, and lets you override them later if you need to. The `defineConfig` helper in the config example suggests the config file is meant to be read and merged, not written from scratch.
The version number is worth noticing as well. The package is at 5.0.0, with release candidates 5.0.0-rc.2 and 5.0.0-rc.3 in May 2026 and the final on 2026-09-27, so this is a tool that has been through several major versions and has settled on a shape.
What the defaults actually include
The feature list is short and each entry answers a question you would otherwise answer yourself.
Language and asset support: JavaScript, TypeScript, JSX, CSS, SCSS, and assets. Toolchain: SWC, core-js polyfills, and Lightning CSS. That trio is the interesting part. SWC is the compiler doing the transforming. core-js polyfills means the output targets older browsers without you picking a polyfill strategy. Lightning CSS handles the CSS processing.
Development: hot reloading, including React fast refresh, which is a specific feature rather than a generic one, because fast refresh preserves component state across edits and is the difference between a hot reload that is usable and one that resets your form every keystroke.
Production: content-hashed production builds with code splitting and an asset manifest. The asset manifest is the part that matters for deployment, since it is the map from a hashed filename to a logical name that a server or a CDN configuration needs in order to set long cache headers on the hashed files and short ones on the entry point.
Also in the list: optional modern/legacy differential builds, dev proxying, static serving middleware, and CSP nonce helpers. The CSP nonce helper is a small, thoughtful inclusion, since Content Security Policy nonces have to be threaded through the HTML and the script tags, and a bundler that generates them is saving you a category of bug.
And a small config file when defaults are not enough, which is the framing of the whole tool. Every entry is a decision pre-made, and the config file exists to undo the ones you disagree with.
A config file with four namespaces
When you do need to configure Jetpack, the file is `jetpack.config.js`, `jetpack.config.mjs` or `jetpack.config.cjs`, and the guidance is to keep common app options top-level and put build and HTML shell settings under `build` and `html`.
The full example:
import { defineConfig } from 'jetpack'
export default defineConfig({
entry: '.',
port: 3030,
assetBaseUrl: '/assets/',
dev: {
overlay: true
},
build: {
outDir: 'dist',
chunkLoadRetry: true
},
html: {
title: 'my-app'
},
css: {
modules: true
}
})Reading the shape tells you what the tool thinks the important axes are. Top-level holds what most projects change: the entry, the port, and `assetBaseUrl`, which is the public path prefix for built assets and the setting you must get right when the app is served from a subdirectory rather than a domain root. Then a `dev` block, a `build` block, an `html` block for the document shell, and a `css` block.
Two of those settings reveal behaviour worth knowing about. `dev.overlay` is the error overlay, the full-screen error display in the browser that a dev server shows when a build fails, and it is on by default here. And `build.chunkLoadRetry` is a resilience setting for dynamically imported chunks, so that a chunk that fails to load is fetched again rather than leaving the app stuck on a blank screen after a deploy, which is a real failure mode when a user has an old page open and the server has moved on.
The `css.modules` option switches on CSS modules, and the repository has an example directory for exactly that case, `with-css-modules`.
Mounting Jetpack inside an existing server
The most interesting part of the API is the ability to run Jetpack as middleware rather than as a separate process.
The pattern is to mount it after your own API routes:
import { serve } from 'jetpack/serve'
app.get('/api/unicorns', (req, res) => res.json([]))
app.use(serve())The order matters and the example makes the point: Jetpack goes after the API routes, so your API wins the path match and Jetpack handles everything else.
The behaviour of `serve()` is described in detail, and it is the sort of detail that usually goes undocumented. It resolves Jetpack config on the first request and caches the middleware, so the config file is read once rather than on every request. It uses `process.cwd()` as the default project directory, proxies to the Jetpack dev server outside production, and serves `build.outDir` in production.
So the same middleware call does two quite different things depending on the environment. In development it is a reverse proxy to a separate dev server process, and in production it serves the built static files directly. That is a genuinely useful design, because it means the server file in development and the server file in production are the same file, with the difference handled by the environment rather than by a branch in your code.
For a monorepo, you pass the client directory:
app.use(serve({ dir: clientDir }))The repository has examples for this with both Express and Fastify, so the `examples/serve-with-express/` and `examples/serve-with-fastify/` directories show the integration with each of those.
The other examples in the repository cover the ground a new project needs: a hello world, a lazy-loading example for code splitting, a with-css-modules example, and a with-react example.
The commands beyond start and build
There is a set of utility commands for the cases that are not the happy path, and they are where the tool's ergonomics show.
Pointing Jetpack at another file or project:
jetpack ~/Desktop/magic.js
jetpack --dir ~/projects/appSo a single script can be run without a project scaffold, which is useful for trying a thing out, and the `--dir` flag points the tool at a different directory.
And then the inspection and maintenance commands:
jetpack inspect
jetpack clean --dry-run
jetpack browsers --coverage=GB`inspect` is the one to reach for first, because when a preconfigured tool does something you did not expect, you need to see what it decided rather than guess. `clean --dry-run` is a dry run of the clean operation, which is the polite way to find out what a command would delete. And `browsers --coverage=GB` is the browser targets query, and the coverage argument is a market share style percentage used to decide which browsers your browser targets need to cover, which is what decides whether you need the optional modern and legacy differential builds the feature list mentions.
The default dev server is on `http://localhost:3030` and the default build output is `dist/`.
The repository structure is worth a quick note. There are separate entry points at the top level for the different export paths, `index.js`, `rspack.js`, `rspack-config.js`, `html.js` and `serve.js`, each with a matching `.d.ts`, and the package exports map has an entry for each with types, import and default conditions. So the subpath imports are first class and typed, not an afterthought bolted on to a single main entry.
The `rspack-config` export in particular is the escape hatch: it is how you get at the underlying Rspack configuration rather than only the curated subset Jetpack exposes. The `rspack` export is presumably the bundler itself re-exported.
The tooling is lean and modern. Tests are ava, types are checked with `tsc -p tsconfig.types.json`, coverage comes from c8, and linting and formatting use oxlint and oxfmt, with the formatter config in `.oxfmtrc.json` and the linter config in `.oxlintrc.json`. The release process uses `np` for the version and publish, with a separate `release-rc` script that publishes under the `next` tag, which is the standard way to get a release candidate into a separate npm dist-tag.
The licence is MIT, the last push was on 2026-09-27, and the repository is not archived.
Editorial conclusion
Jetpack fits a developer starting a web project who wants a sensible Rspack configuration on the first run, since the defaults cover TypeScript, JSX, CSS and SCSS, polyfills, minification and content hashing without you writing any of it. Skip it if you already have a bundler configuration you are happy with, since Jetpack's value is exactly the part you would be replacing, and check the Node requirement before you start, because the package declares `^20.19.0 || >=22.12.0` and is published as ESM. Before you rely on it, run `jetpack inspect` and `jetpack browsers --coverage=GB` to see what the defaults actually do for your project, and note the release history, with v5.0.0 on 2026-09-27 after two release candidates in May, so a major version just landed.
Frequently asked questions
How do I install and run Jetpack?
Run `npm install -g jetpack`, then `jetpack` to start a dev server on http://localhost:3030 and `jetpack build` to build into dist/. Jetpack requires Node 20 or newer and is published as ESM.
What does Jetpack include by default?
JavaScript, TypeScript, JSX, CSS, SCSS and assets, plus SWC, core-js polyfills and Lightning CSS, hot reloading with React fast refresh, content-hashed production builds with code splitting and an asset manifest, and dev proxying with CSP nonce helpers.
How do I configure Jetpack?
Add a `jetpack.config.js`, `jetpack.config.mjs` or `jetpack.config.cjs` file and use the exported `defineConfig` helper, keeping common app options top-level and putting build and HTML shell settings under the `build` and `html` keys.
Can I mount Jetpack in an Express or Fastify server?
Yes. Import `serve` from `jetpack/serve` and call `app.use(serve())` after your API routes. It resolves the config on the first request and caches it, proxies to the dev server outside production and serves build.outDir in production, and you can pass a dir for monorepos.
What do the jetpack inspect and browsers commands do?
`jetpack inspect` reports what the tool has decided about the project, `jetpack clean --dry-run` shows what a clean would remove without doing it, and `jetpack browsers --coverage=GB` reports browser targets against a coverage percentage.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kidkarolis-jetpack)Was this useful?