MainPage

Contentsgarten is an open-source headless, modern, cloud-native wiki engine.

For team wikis, and collaborative digital gardens — check out the use cases page for more information.

Instances

This wiki engine is currently being used on:

SiteFrontendHosting
Creatorsgarten websiteAstroDeploys.app
Contentsgarten wiki (you are here!)RemixNetlify
wiki.wonderful.softwareNext.jsHop.io

Goals

  • Contents are stored on a GitHub repo.
  • Uses a separate authorization layer from GitHub. Authorized users can make changes to the wiki page through the web interface if the authorization rules allows for it, even if the user does not have write access to the repo. (This effectively skips the pull request and invitation workflows.)
  • Uses Markdown as a native markup format.
  • Pages can include templates and other rudimentary logic using Liquid tags.
  • Users authenticate using GitHub via Firebase Auth.
  • Public API available that can be called on the client side.
  • Should be free-to-host for small wikis.
    • Serverless route: The wiki can be hosted on Netlify or Vercel (free plan available).
    • Stateful route: The wiki can be hosted on a server that runs containers (free usage quota is available on Fly.io, Railway.app, Hop.io, Google Cloud Run, Azure Container Apps, and Deploys.app).
  • Can be used as a library.
  • 🚧 Automatic hierarchy. Do you always have a messy Notion sidebar despite your effort in trying to organize it? Contentsgarten aims to automatically organize pages based on how pages are linked together.

🚧 = future goals (unimplemented)

Architecture

  • The core wiki engine is a tRPC router, which allows integrating into any Node.js app.
  • Authentication is handled through Firebase Authentication or through custom auth.
  • GitHub is source of truth, with MongoDB as a local cache.
  • Encourages the stale-then-revalidate fetching style. On server rendering, possibly-stale data will be fetched from the cache to render the page as soon as possible. Once the page is loaded, client-side JavaScript kicks in and makes another request to update the page from GitHub.