An open API service indexing awesome lists of open source software.

https://github.com/crowi/crowi

Crowi - The Markdown Wiki - Empower the team with sharing your knowledge
https://github.com/crowi/crowi

crowi knowledge markdown-wiki typescript wiki

Last synced: 4 days ago
JSON representation

Crowi - The Markdown Wiki - Empower the team with sharing your knowledge

Awesome Lists containing this project

README

          


Crowi

Crowi


The Markdown Wiki — empower the team with sharing your knowledge.



GitHub Actions CI


> [!CAUTION]
> **Crowi v2 — codename *Reignite* — is in active prerelease.**
>
> - Prereleases are published (latest **`2.0.0-alpha.3`**) and support an in-place
> upgrade from a v1 MongoDB. There is no *stable* v2 yet, so the API / config
> surface can still change between alphas — pin a version and read the release
> notes. For a real deployment use a published release, not this branch's HEAD.
> - Crowi v1.x is deprecated and unmaintained.
> - Track progress in [`TODO.md`](./TODO.md), the [docs](https://crowi.wiki), and the
> [v2 announcement on Zenn](https://zenn.dev/sotarok/articles/34795a35a4ef74).

## What is Crowi

Crowi is a **Markdown Wiki** for team knowledge sharing. URL paths *are* the
page hierarchy, so `/team/handbook/onboarding` reads exactly the way it's
written. v2 ("Reignite") rebuilds the stack from Express + Swig + jQuery
to a **Hono API + Next.js 16 (App Router) + React 19**, while keeping v1's
MongoDB data shape intact — your existing wiki migrates over.

**v2 highlights:** real-time collaborative editing (Yjs / Hocuspocus), an
embedded Model Context Protocol (MCP) server for AI agents, OAuth 2.0 +
personal access tokens, a pluggable storage / search / renderer / mail
architecture, sensitive-config encryption (AES-256-GCM), dark mode, and the
`@crowi/cli` end-user CLI.

## Monorepo layout

This repository is a Turborepo + pnpm workspace.

```
crowi/
├── apps/
│ ├── crowi-runner/ # Reference runner project (@crowi/runner-app): dev launch
│ │ # point + build source for the full Docker image. Owns
│ │ # @crowi/api + the full plugin set + crowi.config.json.
│ ├── crowi-runner-slim/ # Minimal runner project: build source for the slim Docker
│ │ # image (core + a minimal plugin set)
│ └── crowi-site/ # crowi.wiki LP + docs (Next.js + Fumadocs, port 4303)
├── .env.example # Dev runtime env template (copy to .env)
└── packages/
├── api/ # Hono 4 API library (port 4301)
├── api-contract/ # Shared Hono (@hono/zod-openapi) contracts + Zod schemas
├── web/ # Next.js 16 frontend (port 4302)
├── collab/ # Realtime collab server (Yjs / Hocuspocus), attached to the api
├── runner/ # Config loader + plugin resolver (used by @crowi/api boot)
├── cli/ # `@crowi/cli` end-user CLI (read / write / search over the HTTP API)
├── admin-cli/ # `crowi-admin` CLI (init / migrate / re-encrypt; DB-direct)
├── plugin-api/ # Plugin SDK (CrowiPlugin / registries / context)
├── plugin-aws/ # Shared AWS credentials base plugin
├── plugin-storage-local/ # Default-on local FS storage driver
├── plugin-storage-aws-s3/ # S3 storage driver
├── plugin-search-elasticsearch/ # Elasticsearch search driver
├── plugin-search-opensearch/ # OpenSearch search driver
├── plugin-search-mongo/ # MongoDB-native search driver (no external service)
├── plugin-mail-smtp/ # SMTP mail transport
├── plugin-mail-resend/ # Resend mail transport
├── plugin-mail-aws-ses/ # AWS SES mail transport
├── plugin-renderer-emoji/ # `:emoji:` → 🎉 renderer
├── plugin-renderer-katex/ # KaTeX math renderer
├── plugin-renderer-plantuml/ # PlantUML diagram renderer
└── plugin-renderer-crowi-legacy/ # v1-era wikilinks / strikethrough / etc.
```

The API package is plugin-agnostic at runtime — `@crowi/runner`
resolves plugin npm names against the runner project's `node_modules/`
via `createRequire(/package.json)`. Operators add a plugin
by declaring it in their runner's `package.json` deps and listing it
in `crowi.config.json:plugins`; the api never needs to be rebuilt.

## Tech stack

- **API**: Hono 4 + `@hono/zod-openapi` + Mongoose + JWT auth (`jwtAuth` middleware); OAuth 2.0 + PAT; embedded MCP server
- **Realtime**: Yjs + Hocuspocus, attached to the api process (`@crowi/collab`)
- **Web**: Next.js 16 (App Router, Turbopack) + React 19 + Tailwind CSS v4 + shadcn/ui + @tanstack/react-query
- **Site**: Next.js 16 (static export) + Fumadocs UI + i18n (ja / en)
- **Shared**: TypeScript 5.x strict, pnpm workspaces, Turborepo
- **Lint / Format**: Biome (format) + ESLint (lint), lefthook hooks
- **Tests**: Jest + supertest + mongodb-memory-server (API + collab)

## Requirements

- Node.js 24.x
- pnpm 10.x (pinned via `packageManager` in `package.json`)
- MongoDB
- Redis
- A search backend (optional, plugin-driven): Elasticsearch / OpenSearch, or the external-service-free MongoDB driver
- Docker / Docker Compose (for local infrastructure)

## Local development

```bash
# 1. Install dependencies
pnpm install

# 2. Start dependency services (MongoDB / Redis / Elasticsearch / PlantUML)
docker compose up -d

# 3. Set up env file at the repo root. `pnpm dev` boots the api with cwd =
# apps/crowi-runner (the runner projectDir), so its dev script loads this
# repo-root .env via `--env-file-if-exists=../../.env`. (In production / an
# external runner project, the api reads the .env in its own cwd via dotenv.)
cp .env.example .env
# Edit MONGO_URI / REDIS_URL / PASSWORD_SEED / CROWI_ENCRYPTION_KEY etc.

# 4. Run everything (api on :4301, web on :4302, plugins compiled in watch mode)
pnpm dev
```

Other targeted scripts:

```bash
pnpm dev:api # just the API + plugins (no Next.js)
pnpm dev:web # just the Next.js frontend
pnpm dev:site # crowi.wiki LP + docs (port 4303)
```

## Environment variables

`.env.example` (at the repo root) lists the full set. Highlights:

| Variable | Purpose |
| --- | --- |
| `MONGO_URI` | MongoDB connection string |
| `REDIS_URL` | Sessions + socket.io adapter (use `rediss://` for TLS) |
| `PASSWORD_SEED` | Legacy password hashing seed (still used for fallback verification) |
| `CLIENT_URL` | CORS allowlist origin in production (defaults allow localhost in dev) |
| `CROWI_ENCRYPTION_KEY` | Base64-encoded 32-byte AES-256 key for sensitive Config encryption. Generate via `openssl rand -base64 32` or `pnpm --filter @crowi/api crypto:gen-key`. Strongly recommended to set; missing key falls back to plaintext (legacy behaviour) with a startup warning. |
| `PORT` | API server port (default `4301`) |
| `NODE_ENV` | `production` or `development` |

Storage backend selection is driven by the runner's `crowi.config.json`
(`storage.driver: 'local' | 's3' | ...`) plus the corresponding
`@crowi/plugin-storage-*` package — there is no `FILE_UPLOAD` env any
more.

## Tests / type-check / lint / build

```bash
pnpm test # all apps
pnpm --filter @crowi/api test # api only
pnpm type-check # api + web + site
pnpm lint # all apps; errors=0 required
pnpm build # all
pnpm --filter @crowi/api-contract build # required after editing contracts
```

Format runs automatically via lefthook on commit (Biome).
Manual: `pnpm format` / `pnpm format:check`.

## Plugins

Plugins are regular npm packages declared in the runner project's
dependencies and listed in `crowi.config.json:plugins`. The shipped
first-party plugins live under `packages/plugin-*/`:

- **Storage**: `plugin-storage-local` (default), `plugin-storage-aws-s3`
- **Search**: `plugin-search-elasticsearch`, `plugin-search-opensearch`, `plugin-search-mongo` (no external service)
- **Mail**: `plugin-mail-smtp`, `plugin-mail-resend`, `plugin-mail-aws-ses`
- **Renderers**: `plugin-renderer-emoji`, `plugin-renderer-katex`, `plugin-renderer-plantuml`, `plugin-renderer-crowi-legacy`

Write your own by depending on `@crowi/plugin-api`, exporting a default
`CrowiPlugin`, and adding the package name to your runner's
`crowi.config.json`.

## License

The MIT License (MIT). See [`LICENSE`](./LICENSE).