Installing Pitlane
pitlane is one install for all seven Pitlane packages. Each package is published on its own under @pitlane/*, and pitlane re-exports every one of them through focused subpaths, the way remix re-exports the @remix-run/* packages:
import { remix } from "pitlane/vite-plugin-remix";
import { createAssetResolver } from "pitlane/assets";
import { createTheme } from "pitlane/theme";A subpath has the same exports as the package it re-exports, so every API page under @pitlane/vite-plugin-remix, @pitlane/assets, and the rest applies to the matching pitlane/* import unchanged. The scoped packages stay independently usable. An app that wants only one of them can install it alone.
Install
npm
npm add pitlaneyarn
yarn add pitlanepnpm
pnpm add pitlanebun
bun add pitlanedeno
deno add npm:pitlanevp
vp add pitlanevlt
vlt add pitlanenub
nub add pitlanepitlane declares three peer dependencies, lifted from the packages it installs:
| Peer | Range | Required |
|---|---|---|
remix |
^3.0.0 |
Yes |
vite |
>=8.1.0 |
Yes |
satteri |
^0.10.5 |
Only when a content collection holds .md or .mdx files |
Install pitlane as a dependency, not a dev dependency, whenever the app imports a runtime subpath such as pitlane/assets, pitlane/theme, pitlane/content, or pitlane/data-table-d1. Those imports run in production, so a production install has to include the package that provides them.
pitlane has no command-line interface. To start a new app, copy one of the starter templates.
Subpaths
Bare pitlane has no exports, so import … from "pitlane" fails. Every import names a subpath, and each subpath mirrors a scoped package export:
| Import | Re-exports | Use it for |
|---|---|---|
pitlane/vite-plugin-remix |
@pitlane/vite-plugin-remix |
The remix() Vite plugin |
pitlane/vite-plugin-remix/hmr |
@pitlane/vite-plugin-remix/hmr |
revalidate(), the browser entry's server-update helper |
pitlane/assets |
@pitlane/assets |
createAssetResolver() and renderImportMap() |
pitlane/assets/manifest |
@pitlane/assets/manifest |
The asset manifest the build supplies, passed to createAssetResolver() |
pitlane/assets/build |
@pitlane/assets/build |
createAssetManifest(), for bundler integration authors |
pitlane/assets/vite-plugin |
@pitlane/assets/vite-plugin |
The assets() Vite plugin, for apps without remix() |
pitlane/vite-plugin-fetch-server |
@pitlane/vite-plugin-fetch-server |
The fetchServer() development request bridge |
pitlane/theme |
@pitlane/theme |
createTheme(), css(), and tva() |
pitlane/theme/schema |
@pitlane/theme/schema |
Schema factories |
pitlane/theme/default |
@pitlane/theme/default |
Tailwind CSS v4's primitives as DefaultTheme |
pitlane/theme/dtcg |
@pitlane/theme/dtcg |
Conversion to and from Design Tokens Community Group documents |
pitlane/content |
@pitlane/content |
createContent() and collections |
pitlane/content/loaders |
@pitlane/content/loaders |
The glob() and file() loaders |
pitlane/content/vite-plugin |
@pitlane/content/vite-plugin |
The contentLayer() Vite plugin |
pitlane/content/hot |
@pitlane/content/hot |
Browser reloads for content without a build |
pitlane/content/satteri |
@pitlane/content/satteri |
The headings() and rawStyles() Satteri plugins |
pitlane/crawler |
@pitlane/crawler |
crawl() and staticPaths() |
pitlane/data-table-d1 |
@pitlane/data-table-d1 |
The Cloudflare D1 driver for remix/data-table |
pitlane/data-table-d1/migrations |
@pitlane/data-table-d1/migrations |
generateD1Migrations(), build tooling kept out of the Worker |
A subpath is the scoped package name without its scope, followed by the package's own subpath: @pitlane/theme/schema becomes pitlane/theme/schema.
Versions
Each pitlane release depends on an exact version of every scoped package, and its changelog lists those versions. Installing pitlane@1.0.0-alpha.1 installs the package versions that release was built and documented against, never newer ones.
The umbrella is released by hand when enough package changes have accumulated. A scoped package's newest release can be ahead of the version the current pitlane pins. Need a fix before the next umbrella release? Install that scoped package directly and use its @pitlane/<name> import. Mixing the two explains how the installs coexist.
1.0.0-alpha.1 is the first umbrella release. It pins @pitlane/dev@0.7.1, @pitlane/theme@0.5.0, @pitlane/content@0.3.1, @pitlane/crawler@0.3.0, and @pitlane/data-table-d1@0.3.0. Releases before it, 0.0.x, were a placeholder with no usable exports.
Alpha releases are published to npm's latest tag until a stable 1.0.0 exists, so a plain install picks up the newest alpha. Pin an exact version, such as pitlane@1.0.0-alpha.1, to decide when the app moves to the next one.
Production installs
pitlane installs every package, @pitlane/vite-plugin-remix and its Vite peer included. Because an app with runtime imports lists it in dependencies, a production install that omits dev dependencies still installs the Vite plugins and Vite itself. remix makes the same trade for its CLI and test runner. The cost is install size and time on the production host.
Scoped packages
The scoped packages are the lean alternative. Put @pitlane/vite-plugin-remix in dev dependencies and only the runtime packages the app imports in dependencies. For an app that resolves its assets and uses the theme and content collections:
npm
npm add @pitlane/assets @pitlane/theme @pitlane/content
npm add -D @pitlane/vite-plugin-remixyarn
yarn add @pitlane/assets @pitlane/theme @pitlane/content
yarn add -D @pitlane/vite-plugin-remixpnpm
pnpm add @pitlane/assets @pitlane/theme @pitlane/content
pnpm add -D @pitlane/vite-plugin-remixbun
bun add @pitlane/assets @pitlane/theme @pitlane/content
bun add -D @pitlane/vite-plugin-remixdeno
deno add npm:@pitlane/assets npm:@pitlane/theme npm:@pitlane/content
deno add -D npm:@pitlane/vite-plugin-remixvp
vp add @pitlane/assets @pitlane/theme @pitlane/content
vp add -D @pitlane/vite-plugin-remixvlt
vlt add @pitlane/assets @pitlane/theme @pitlane/content
vlt add -D @pitlane/vite-plugin-remixnub
nub add @pitlane/assets @pitlane/theme @pitlane/content
nub add -D @pitlane/vite-plugin-remixThen import from the scoped names, such as @pitlane/vite-plugin-remix and @pitlane/theme/schema. Choose this when production install size matters, when an app uses a single package, or when it needs a package release newer than the umbrella pins.
Migrate from scoped packages
- Install
pitlaneas shown in Install. - Rewrite the public imports listed in Subpaths from
@pitlane/<name>topitlane/<name>, keeping the listed subpath:@pitlane/content/vite-pluginbecomespitlane/content/vite-plugin, and@pitlane/assets/manifestbecomespitlane/assets/manifest. - Remove a scoped package from
package.jsononly when nothing in the app or its tooling imports it directly.
The umbrella excludes @pitlane/content/internal/*. Custom bundler integrations using those unstable APIs must keep their scoped imports and a direct @pitlane/content dependency. Keep that dependency at the umbrella's pinned content version when both are used, so the plugin and collections share the same content package.
Mixing the two
An app can keep a direct @pitlane/* dependency next to pitlane. Different versions mean two copies of that package. The pitlane/* import reaches the pinned copy, while the @pitlane/* import reaches the direct dependency. Use one import path consistently for each package.
Documentation for coding agents
pitlane releases after 1.0.0-alpha.1 install these guides and every package's README with the package. A coding agent working in the app reads documentation for the version the app depends on, offline, instead of what it remembers or what pitlane.tools last deployed. The layout follows the one remix uses for its installed documentation:
Path in node_modules/pitlane/ |
What it holds |
|---|---|
INDEX.md |
Every guide listed by task and every export listed by subpath, each linking the installed file that covers it |
guides/index.md |
The guides overview |
guides/<slug>.md |
Each guide, such as guides/vite-plugin.md |
guides/deploy/<slug>.md |
Each deploy guide, such as guides/deploy/cloudflare.md |
dist/<package>/README.md |
Each scoped package's README beside its compiled code, such as dist/vite-plugin-remix/README.md for pitlane/vite-plugin-remix and its subpaths |
These are the same Markdown pages pitlane.tools publishes. A link between two of them leads to the installed copy, so following one never leaves the installed version. Links to the API reference stay on pitlane.tools. The installed type declarations carry the same TSDoc, so an editor or agent can read an export's signature and documentation from the .d.ts file instead.
An agent has to know the index exists. Point it there with a line in the app's AGENTS.md:
Before changing Pitlane code, read `node_modules/pitlane/INDEX.md`; prefer the installed documentation over memory or the latest website.An app that installs only scoped @pitlane/* packages has none of these files. It can read the same pages as Markdown through llms.txt, which describes whatever was last deployed.