Contributing
Updated Apr 28, 2026
Livemark is an open-source project and we'd love your help — whether that's fixing a bug, polishing the docs, or proposing a new feature. This guide walks through everything you need to get a change from your editor into a release.
Quick start
You'll need Node.js 24+ and pnpm 10+. Then:
git clone https://github.com/datisthq/livemark.git
cd livemark
pnpm install
pnpm docs:startpnpm docs:start boots the dev server against this repo's own docs/ so you can iterate on Livemark while seeing the result in your browser. Edits to source/ or docs/ reload automatically.
Repository layout
livemark/
├── source/ # all package code (compiles into build/)
│ ├── actions/ # build-time orchestration (config, changelog)
│ ├── commands/ # `livemark <cmd>` CLI entrypoints
│ ├── components/ # React components (overridable via .livemark/)
│ ├── elements/ # shadcn-style primitives (overridable)
│ ├── styles/ # base CSS (overridable)
│ ├── helpers/ # internal utilities (private)
│ ├── hooks/ # public React hooks
│ ├── utils/ # public utilities (e.g. cn)
│ ├── plugins/ # remark / rehype / vite plugins
│ ├── routes/ # TanStack Start routes
│ ├── models/ # Zod schemas
│ ├── content/ # content-collections derivations
│ └── vite.config.ts # the Vite config consumers run against
├── build/ # compiled JS, used by Node CLI
├── docs/ # this site's content
├── blog/ # this site's blog posts
└── livemark.config.ts # this site's livemark config
Both source/ and build/ ship in the npm package: Node loads build/*.js, while Vite bundles raw TS from source/* so the literal .ts import extensions resolve.
Local commands
| Command | What it does |
|---|---|
pnpm docs:start | Run the dev server against this repo's docs |
pnpm docs:build | Production build of the docs site |
pnpm build | Compile source/ → build/ (tsgo) |
pnpm type | Type-check (no emit) |
pnpm lint | Format check + lint via Biome |
pnpm format | Auto-fix formatting |
pnpm unit | Run unit tests (Vitest) |
pnpm test | Lint + type + unit |
A change is ready to push when pnpm test is green and pnpm docs:build succeeds.
Code conventions
- TypeScript: strict mode is on. Don't use
any, theascast, or non-null!without a clear reason — flag it in the PR. - Imports: use full ESM paths with the
.ts(x)extension (from "./foo.ts"). Tsgo rewrites them to.json emit viarewriteRelativeImportExtensions. - Comments: docstrings on exports only. Skip narrative
//comments inside function bodies — let the names do the work. - File layout: high-level public items at the top, private helpers at the bottom.
- Tests: place unit tests in
<module>.unit.tsnext to the code. No "Arrange/Act/Assert" comments — the structure should be obvious. - Formatting: Biome via
pnpm format. 2-space indent, no semicolons, single quotes.
Proposing a change
- Open an issue first for anything bigger than a typo or a small bug. It's much easier to align on direction before code.
- Branch from
mainwith a short descriptive name (e.g.fix-mobile-toc,feat-yaml-frontmatter). - Write a focused commit history. Livemark uses Conventional Commits — the prefix drives semantic-release:
fix:— bug fix → patch releasefeat:— new feature → minor releasefix!:/feat!:orBREAKING CHANGE:footer → major releasechore:,docs:,refactor:,test:— no release
- Run
pnpm testandpnpm docs:buildbefore pushing. - Open a PR against
main. Describe the why (link the issue), include screenshots for any UI change, and call out anything reviewers should pay extra attention to.
Releases
Releases are driven by semantic-release on every push to main. Conventional commit messages decide the next version automatically. Maintainers don't need to bump versions manually.
For a local version bump (e.g. preparing a non-semantic-release branch), use pnpm setversion <new-version> — it sets the version without creating a git tag.
Where to find help
- Bugs and feature requests: GitHub Issues
- Discussion / ideas: GitHub Discussions
- Source: github.com/datisthq/livemark
Thanks for helping make Livemark better.
Built with ❤ and Livemark