Chanom (ชานม) - Brew a Vite + React app, or add lint, format, commit hooks, and CI to the one you have, in a couple of prompts
I created this repository to share my frontend development setup, so others can start a project with the same linting, formatting, commit hooks, and CI without wiring it up by hand. I chose the name "Chanom" because I love milk tea (Chanom) and it would be fitting to think of it as a base milk tea with additional toppings, similar to how you might add additional settings to a React app when creating it.
# 1. Use the Node version pinned in .nvmrc
nvm use # or: fnm use
pnpm install
# 3. Verify everything works
pnpm exec turbo run build lint format:check| Package | Description | README |
|---|---|---|
@chanom/analytics |
Web analytics facade fanning out to GA, GTM, and PostHog | README |
@chanom/cli |
Interactive CLI that brews dev tooling config into your project | README |
create-chanom-app |
Scaffold a Vite + React + TS app wired to the chanom shared configs | README |
@chanom/dev-config |
Shared oxlint + oxfmt presets | README |
@chanom/logger |
Console logger with environment gating and level filtering | README |
@chanom/utils |
Tree-shakable TypeScript utilities for frontend apps | README |
@chanom/vite-config |
Vite config factory for libraries and React apps | README |
- Package manager / workspaces: pnpm with catalogs (
catalogMode: strict) - Task runner / cache: Turborepo
- Versioning / publishing: Changesets
- Lint / format: oxlint / oxfmt
- Build: tsdown, Vite, TypeScript
- Node.js
24.18.0(see.nvmrc) - pnpm
11.9.0(seepackage.jsonpackageManager) - (Recommended) VS Code with the recommended extensions in
.vscode/extensions.jsonoxc.oxc-vscodefor lint/formatvercel.turbo-vscfor Turborepo
Run these from the repo root:
| Command | What it does |
|---|---|
pnpm lint |
Lint the whole repo with oxlint |
pnpm lint:fix |
Lint and auto-fix with oxlint |
pnpm format |
Format the whole repo with oxfmt |
pnpm format:check |
Check formatting without writing files |
pnpm exec turbo run build |
Build all packages in dependency order |
pnpm exec turbo run lint |
Run package-level lint scripts |
pnpm exec turbo run format:check |
Run package-level format:check scripts |
pnpm changeset |
Add a new changeset for a public package |
pnpm changeset:version |
Apply changesets and bump versions/changelog |
pnpm changeset:release |
Build all packages and publish to npm |
-
Create a directory under
packages/<name>. -
Add a
package.json:"name":@chanom/<name>"version": start at0.0.0for new packages"type": "module"- Use catalog versions for third-party deps:
"dep": "catalog:" - Reference workspace packages with
"workspace:*"
-
Add
README.md, source files, and atsconfig.jsonif it is a TypeScript package. -
Add the usual scripts:
build,dev(when applicable)lint/lint:fixformat/format:check
-
Run
pnpm installso pnpm picks up the new workspace member. -
Build and verify:
pnpm --filter @chanom/<name> build pnpm exec turbo run build lint format:check
-
If the package will be published, run
pnpm changesetbefore opening a PR.
Look at packages/vite-config for a complete example of a buildable, publishable package.
Packages are published under the @chanom scope. See the individual package READMEs for install and usage examples:
This repo uses Changesets.
Typical flow:
-
Make your changes.
-
Run
pnpm changesetand follow the prompts. -
Commit the generated changeset file along with your code.
-
After the PR is merged to
main, run:pnpm changeset:version # bump versions and update changelogs pnpm changeset:release # build all packages and publish
baseBranch is main and new packages are published publicly by default (see .changeset/config.json).
The repo ships shared VS Code settings in .vscode/settings.json:
- Default formatter: OXC
- Format + fix on save enabled
- Custom words added to the spell checker
- Roadmap:
- Vitest preset in
@chanom/vite-config -
create-chanom-appCLI - Shared
tsconfigpreset in@chanom/dev-config - Analytics package
- Vitest preset in
-
pnpm exec turbo run build lint format:checkpasses - A changeset is added if a public package changed
- The new package or app has a
README.md