Contributing
Internal guide for developing the evjs monorepo.
Project Identity
- Name: evjs, package scope
@evjs/* - Repository: afx-team/evjs
- CLI:
evfrom@evjs/cli - Linter: Biome
- Modules: ESM-only
Setup
git clone https://github.com/afx-team/evjs.git
cd evjs
npm install
Commands
npm run build
npm run test
npm run test:e2e
npm run check-types
npm run lint
npx biome check --write
Coding Rules
- Keep imports at the top and use
import typefor type-only imports. - Use Biome formatting and linting. Avoid
anyand broad namespace imports without a concrete reason. - New applications use one Page-and-Route model:
src/pages/**/page.*, optional build-timepage.config.ts, directory-derived URLs, androuting.mode. - Keep Page-private components, hooks, models, services, tests, and styles
inside that Page directory. They do not need
_. - Canonical client route directories use
$param, terminal$...splat, and(group). Server request Routes use strictsrc/apis/**/api.*positive anchors with directory-derived URLs. - New runnable examples use
page.*,page.config.ts, androuting.mode. Keep explicitapplication.routescases in focused config-route fixtures. - Server functions begin with
"use server";and export named callables. - Config/build imports stay on
@evjs/ev; app source uses@evjs/ev/route,/navigation,/query,/server-context, and/transport. Standalone runtimes import@evjs/clientor@evjs/server. - Keep framework semantics in
@evjs/evbuild internals and normalized contracts in@evjs/shared/manifest. Bundler adapters consume BuildPlan and return facts. .ev,dist,.turbo,node_modules, and route-type declarations are generated output.
Common Tasks
Add A Page Route
- Create
src/pages/<url-segments>/page.tsx. - Default-export the Page component.
- Use
$param, terminal$...splat, or(group)directories when needed. - Put Page-private source in the same directory; no
_prefix is required. - Add
page.config.tswhen the Page needs a static title, supported named metadata, core rendering fields, or Page settings for an installed plugin. Runtime use of plugin settings requires explicit plugin projection.
Add A Server Function
- Create a reachable
[name].server.tsbeside its caller or domain code. - Add
"use server";at the top. - Export named async callables.
- Consume them through
@evjs/ev/query.
Add A Server File Route
- Create the URL directory under
src/apisand add itsapi.tsanchor. - Export uppercase HTTP handlers such as
GETorPOSTfrom the anchor. - Keep helpers in ordinary colocated non-
api.*modules. - Use
src/middleware.tsorsrc/apis/**/middleware.tsfor middleware.
Add An Example
- Add a private workspace package under
examples/. - Use canonical
routing.modeandpage.*route directories. - Add
index.htmland the required workspace dependencies. - Add/update create-app mapping only when it is a supported user template.
- Add focused unit/e2e validation.
- Keep explicit route-tree cases in clearly named config-route fixtures, not canonical templates.
Change Page Or Route Conventions
- Update config resolution and graph normalization first.
- Update English and Chinese
project-structure,file-conventions, config, and relevant examples together. - Add graph, diagnostics, scaffold, and config-route coverage.
- Run the repository validation gates.
Release A Version
- Create a GitHub Release with the
vX.Y.Ztag for the version being released. - Release automation synchronizes internal package versions and publishes.
- Do not bump workspace-internal
"*"dependencies locally.