.agents/skills/add-package/SKILL.md
Create or align a package in the Remix monorepo to match existing package conventions. Use when adding a brand new package under packages/, or when fixing an existing package's structure, test setup, TypeScript/build config, code style, and README layout to match the rest of Remix 3.
npx skillsauth add remix-run/remix add-packageInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill to scaffold and standardize packages so they look and behave like the existing @remix-run/* packages.
Follow this exactly when creating package files, public exports, tests, and docs.
packages/<package-name>/.package.jsontsconfig.jsontsconfig.build.jsonCHANGELOG.mdREADME.mdLICENSE.changes/README.mdsrc/CHANGELOG.md with ## Unreleased as the first section to indicate changes are not released yet.package.json using monorepo conventions.name: @remix-run/<package-name>version (for brand-new packages): "0.0.0"type: "module"license: "MIT"repository.directory: packages/<package-name>homepage: https://github.com/remix-run/remix/tree/main/packages/<package-name>#readmefiles:
LICENSEREADME.mddistsrc!src/**/*.test.tsbuild: tsgo -p tsconfig.build.jsonclean: git clean -fdXprepublishOnly: pnpm run buildtest: node --disable-warning=ExperimentalWarning --testtypecheck: tsgo --noEmit"@types/node": "catalog:""@typescript/native-preview": "catalog:"keywords like existing packages (short, lowercase, feature-focused).src entry files only.exports, map each public subpath to a dedicated file in src../package.json.publishConfig.exports with dist output:
types: ./dist/<entry>.d.tsdefault: ./dist/<entry>.jssrc file that re-exports from src/lib.
./foo -> src/foo.ts -> export { ... } from './lib/foo.ts'Use this tsconfig.json pattern:
{
"compilerOptions": {
"strict": true,
"lib": ["ES2024", "DOM", "DOM.Iterable"],
"module": "ES2022",
"moduleResolution": "Bundler",
"target": "ESNext",
"allowImportingTsExtensions": true,
"rewriteRelativeImportExtensions": true,
"verbatimModuleSyntax": true
}
}
Use this tsconfig.build.json pattern:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"outDir": "./dist"
},
"include": ["src"],
"exclude": ["src/**/*.test.ts"]
}
src/<entry>.ts for public entry pointssrc/lib/*.ts for implementationsrc/lib/*.test.ts for tests (colocated with implementation)import * as assert from 'node:assert/strict'import { describe, it } from 'node:test'describe().import type { ... } and export type { ... } for types..ts extensions in relative imports.let for locals; use const only at module scope.var.method() {}) instead of arrow properties.#private members.# <package-name>## Features## Installation## Usage## Related Packages (if applicable)## Licenseremix package.npm i remix
npm i remix <peer-dependency>
Usage examples must always import from remix package exports, not from @remix-run/<package-name> directly.
License section format:
See [LICENSE](https://github.com/remix-run/remix/blob/main/LICENSE)remix package in PRs.packages/remix is generated automatically in CI.packages/remix/package.json or packages/remix/src/* in new pull requests.packages/remix/.changes/* change files in new pull requests.README.md package list when applicable.pnpm --filter @remix-run/<package-name> run typecheckpnpm --filter @remix-run/<package-name> run testpnpm --filter @remix-run/<package-name> run buildpnpm run lintpackages/<package-name>/.changes/ when requested by contribution workflow.minor. filename (for example, minor.initial-release.md) so the first release bumps 0.0.0 to 0.1.0.packages/remix/.changes/; remix package updates are CI-generated.Use this minimal src/index.ts style:
export { createThing, type ThingOptions } from './lib/thing.ts'
Use this minimal test style:
import * as assert from 'node:assert/strict'
import { describe, it } from 'node:test'
import { createThing } from './thing.ts'
describe('createThing', () => {
it('returns expected value', () => {
let result = createThing()
assert.equal(result, 'ok')
})
})
tools
Build the UI of a Remix app. Use when creating pages, layouts, client entries, interactions, stateful UI, navigation, hydration, styling, animations, reusable mixins, or UI tests.
development
Describe the ideal layout of a Remix application, including canonical directories, route ownership, naming conventions, and file locations on disk. When asked to bootstrap that layout in a new directory, run the bundled TypeScript script.
documentation
Write or rewrite package README files in the style used by the Remix repository. Use when drafting a new package README, revising an existing README, or reviewing README structure, examples, installation instructions, and section ordering for Remix packages.
development
Write or audit public API docs for Remix packages. Use when adding or tightening JSDoc on exported functions, classes, interfaces, type aliases, or option objects.