Static notes site generated from a private Obsidian vault, supporting interactive databases, Jupyter notebook imports, LaTeX equations, and extensible plugins.
- imports topics from vault directories that contain
_index.md - imports note pages from markdown files inside each topic directory
- imports Jupyter notebooks (
.ipynb) as note pages - imports CSV files (
.csv) as interactive database pages - copies relative assets from
./assets/... - builds a static Astro site with light/dark themes
- renders LaTeX via KaTeX
- deploys to GitHub Pages through GitHub Actions
- rebuilds automatically when the private vault repository updates
- plugin system: extends vault processing, Astro configuration, global styling, client scripts, preferences, and navigation links.
src/
content/
notes/ generated note markdown
topics/ generated topic markdown
data/generated/ generated topic metadata
pages/ Astro routes
styles/ Global and layout CSS stylesheets
widgets/ Astro UI components (database, preferences, sidebar)
scripts/
sync-vault.mjs imports vault content into the site
sync-vault/ sync implementation modules
plugins/ Git submodules containing extensible plugins
.github/workflows/
deploy.yml build and deploy workflow
scripts/sync-vault.mjs is the CLI entrypoint and orchestration layer. The implementation details live in scripts/sync-vault/:
env.mjsreads values from.envignore-rules.mjsparses.notegenignoreand checks ignored pathsmarkdown.mjsparses frontmatter and prepares Markdown summaries/contentnotebooks.mjsconverts Jupyter notebooks into Markdown and output assetscsv.mjsparses CSV files and infers database column typesassets.mjscopies local assets and rewrites Markdown/HTML asset linkschangelog.mjsparses changelog events and renders generated changelog datavault-files.mjswalks the vault and resolves topic ancestrysite-config.mjsreads vault-levelnotegen.config.jsonpaths.mjsnormalizes site paths, slugs, and generated content filenamesfs-utils.mjscontains small filesystem helpers shared by sync modulesdata-file.mjsrenderssrc/data/generated/topics.tsplugins.mjsregisters and runs vault compilation hooks for active plugins
To maintain a consistent codebase across developers and environments, the repository includes standard files:
- .editorconfig: Enforces uniform indent sizes, trim whitespace, line endings, and file formatting in editors.
- .gitattributes: Normalizes code file line endings (
lf) and specifies binary attributes for media assets.
npm installVAULT_PATH=./vaultVAULT_PATH should point to a local checkout or fixture copy of your Obsidian vault.
npm run sync:vaultnpm run devNotegen features a plugin architecture allowing you to extend the core compilation, injection of client-side styles and scripts, and UI layout.
Available plugins live under the plugins/ directory.
An active plugin plugins/supabase provides database state synchronization and OAuth/Email user auth.
A fully self-contained showcase testing environment exists inside plugins/supabase/showcase/. It spins up local PostgreSQL, GoTrue auth, PostgREST API gateway, and an Astro client replica.
Run it locally:
./plugins/supabase/showcase/run-test.shAccess points:
- Astro Client:
http://localhost:4321 - pgweb Database Explorer:
http://localhost:8082
Each topic is a directory in the vault:
vault/
database.csv
optimization_methods/
_index.md
karush_kuhn-tucker.md
papers.csv
assets/
image.png
Expected conventions:
- a topic directory must contain
_index.md _index.mdmay contain frontmatter such astitle,slug,draft,description- note files may be Markdown (
.md) or Jupyter notebooks (.ipynb) - Markdown note files may contain frontmatter such as
title,slug,date,status,tags tagsshould be an array of strings:tags: ["ai", "nlp"]. Tags are color-coded based on the site accent color.- CSV files (
.csv) are imported as database pages; top-level CSV files appear on the home page, and CSV files inside a topic appear in that topic - note
statusvalues aredraft,in-progress, ordone; legacydraft: truemaps tostatus: draft, and legacydraft: falsemaps tostatus: done - Jupyter notebooks are converted during
npm run sync:vault: markdown cells become page Markdown, code cells become syntax-highlighted code blocks, and supported outputs are rendered as HTML, text blocks, or copied image assets - Jupyter notebooks may define note metadata through
notebook.metadata.notegenor through YAML frontmatter in the first markdown cell - relative assets should be referenced like

- use the first row as column headers
- support comma, semicolon, and tab delimiters
- infer column types as
text,number,date, orboolean - render boolean values as compact checked/unchecked controls. Boolean columns are fully interactive (click cell to toggle) and persist states locally or via cloud.
- include search, per-column filters, column sorting, column visibility controls, and visible-row counts
- use the filename as the database title and slug
CSV example:
title;year;read
Attention Is All You Need;2017;true
Scaling Laws;2020;falseEach notes repository can override frontend text by adding notegen.config.json to the vault root:
{
"changelogPath": "changelog.json",
"siteText": {
"ru": {
"brand": "Статьи wiki",
"heroTitle": "Статьи wiki",
"metaDescription": "Статьи и заметки.",
"heroBody": "Материалы, заметки и тексты."
},
"en": {
"brand": "wiki articles",
"heroTitle": "wiki articles",
"metaDescription": "wiki articles and notes.",
"heroBody": "Articles, notes, and long-form writing."
}
}
}By default the build reads $VAULT_PATH/notegen.config.json. Use SITE_CONFIG_PATH to point to another config file.
Add .notegenignore to the vault root to skip files and directories during import:
# Do not import repository docs as notes
README.md
# Ignore any directory with this name
drafts/
# Ignore a path from the vault root
private/meeting-notes.md
# Ignore copied note assets
raw/
*.tmpRules are matched relative to the vault root. Directory rules ending with / skip the directory and everything inside it.
notegen uses GitHub Actions for build and deploy:
- the vault repository sends
repository_dispatchwith eventvault-updated - this repository checks out the private vault repo during CI
npm run sync:vaultgenerates site content- Astro builds the static output
- GitHub Pages publishes
dist/
The Docker image builds the static site from a mounted vault repository.
Pushes to main and version tags publish the frontend image to GitHub Container Registry:
ghcr.io/<github-owner>/notegen:latest
ghcr.io/<github-owner>/notegen:v0.1.0
ghcr.io/<github-owner>/notegen:sha-<commit>
docker run --rm \
-v "$PWD/vault:/vault:ro" \
-v "$PWD/dist:/out" \
-e ASTRO_SITE="https://example.github.io" \
-e ASTRO_BASE="/notegen" \
notegenDuring npm run sync:vault, notegen reads the changelog file from the vault root and generates a /changelog page. The default file is vault/changelog.json.
The parser accepts either a JSON array or JSON Lines format.
Event fields:
timestamp: ISO date string, for example2026-05-06T22:40:00Zaction:created,updated,deleted,renamedkind:note,topic,database,assetpath: current path relative to the vault rootoldPath: previous path for renamed filestitle: display titletopic: display topicsource: optional label (e.g.pre-commit)