An Obsidian plugin.
- Create a new repository from this template.
- Replace the placeholders:
package.json:name,description,authormanifest.json:id,name,description,authoreslint.config.js: thebrandslist underobsidianmd/ui/sentence-casemain.ts: the class name. It holds only lifecycle methods; everything else is started fromsrc/runtime.ts.LICENSE: the holder.coverage/baseline.jsonstays at zero until the first real coverage run; then raise it by hand.
- Reset
versions.jsonto the plugin's first version andminAppVersion. - Fill in
docs/TESTING.mdas load-bearing behaviors appear.
Requires Node 24 or later and pnpm.
pnpm install
pnpm dev # rebuild on change
pnpm dev:mobile # same, with mobile emulation
pnpm test
pnpm test:ratchet # coverage, then the floor check
pnpm lint
pnpm typecheck
pnpm build # typecheck, then a production build into dist/
Builds land in dist/. Symlink a dev vault's plugin folder to it:
ln -s "$(pwd)/dist" "<vault>/.obsidian/plugins/<plugin-id>"
The base template has no React. To add it:
pnpm add react react-domandpnpm add -D @types/react @types/react-dom @testing-library/react- In
tsconfig.json, add"jsx": "react-jsx", extendtypeswith"react"and"react-dom", and changeincludeto["**/*.ts", "**/*.tsx"].
esbuild.config.js, eslint.config.js and vitest.config.js already handle .tsx.
ci.yamlruns typecheck, lint, tests with coverage, the coverage ratchet and a build on every pull request. Branch-protectmainso every change goes through it.release.yamlruns when a GitHub Release is published. The tag must be the bare version and matchmanifest.json. It builds, attests and uploadsmain.js,manifest.jsonandstyles.css.