EEPNext.js Template
Conventions

Git

Branching, commits, stacked PRs, and the pre-commit hook.

These are general conventions any team can adopt and adapt - follow them and they should set you up for a solid, consistent workflow. They also form the basis of how we work on this project itself, so if you're contributing back to the template, see CONTRIBUTING.md for the full contribution guidelines.

Branches

Branch names follow a consistent format so the history is scannable and CI can infer intent from the name.

<type>/<issue-number>-<brief-description>

feat/EEP-123-user-invitations
fix/EEP-456-session-expiry

Types:

  • feat/ - new features
  • fix/ - bug fixes
  • Ad-hoc (no issue): fix/<brief-description> is fine for small isolated fixes

Commits

Commit messages follow Conventional Commits. At minimum, every commit message starts with one of:

feat:      new feature
fix:       bug fix
refactor:  code change that neither fixes a bug nor adds a feature
chore:     tooling, dependencies, config
docs:      documentation only
BREAKING CHANGE: incompatible API change
feat: add user invitation flow
fix: resolve session expiry on mobile
chore: bump drizzle-kit to 0.21
docs: add git conventions page

Stacked PRs

For large changes, stack branches rather than opening one giant PR. Each branch builds on the previous one, so you get smaller, reviewable diffs and can merge incrementally.

main
 └── feat/EEP-100-payments-foundation     ← merged first
      └── feat/EEP-101-payments-ui        ← depends on foundation
           └── feat/EEP-102-payments-webhooks
# Start from the base branch, not main
git checkout feat/EEP-100-payments-foundation
git checkout -b feat/EEP-101-payments-ui

When the base branch merges, rebase the dependent branch onto main:

git checkout feat/EEP-101-payments-ui
git rebase main

Pre-commit hook

The pre-commit hook is intentionally aggressive. If you're not used to this level of enforcement it will feel pretty heavy at first. A full typecheck, test run, and build on every commit is not typical but it's setup like this by design!

When you're working with an agent, unchecked commits are how a codebase quietly spirals. Types drift, tests go red, the build breaks and by the time anyone notices, the damage is spread across ten commits. The hook is the guardrail that keeps that from happening. It's the single most effective thing in this template for keeping agentic workflows from going off the rails.

The hook is powered by Husky and lint-staged. Husky registers the hook with git and runs .husky/pre-commit on every commit. lint-staged runs ESLint and Prettier against staged files only, so you're never linting the whole codebase, just what's about to be committed.

The hook itself is a bash script located at .husky/pre-commit.

TriggerWhat runs
Any staged .ts / .tsx or config changetsc --noEmit + full test suite + build
package.json or pnpm-lock.yaml changedTrivy security scan
eslint.config.ts changedESLint config probe
All commitslint-staged (ESLint + Prettier on staged files)
No relevant changesHeavy checks skipped automatically

Escape hatch - for intentional WIP or a TDD red phase only:

SKIP_CHECKS=1 git commit -m "wip: rough sketch"

Lint, Trivy, and style still run even with SKIP_CHECKS=1. Never use it to bypass failing tests on shippable code.


On this page