by bento

Joplin is a free, open-source note-taking and to-do application supporting Markdown, end-to-end encrypted sync across Nextcloud, Dropbox, OneDrive, and Joplin Cloud, with plugins, web clipping, and clients for desktop, mobile, and terminal.
This block delivers the full Joplin monorepo packages/ tree: CLI, desktop (Electron), mobile, server, renderer, core library, and all supporting packages. The typical buyer is a backend or full-stack developer embedding Joplin's note-taking engine, sync, encryption, or rendering pipeline into an existing Node.js or Electron application.
app-cli/ - Terminal-based Joplin client; commands, REPL GUI, resource serverapp-clipper/ - Browser extension (Firefox/Chrome) for clipping web pages to notesapp-desktop/ - Electron desktop application (main + renderer processes)app-mobile/ - React Native mobile application (iOS/Android)default-plugins/ - Bundled Joplin plugins shipped with desktop buildsdoc-builder/ - Documentation generation toolingeditor/ - CodeMirror-based note editor componentfork-htmlparser2/ - Patched htmlparser2 fork used by the rendererfork-sax/ - Patched sax XML parser forkfork-uslug/ - Patched uslug (URL slug generation) forkgenerate-plugin-doc/ - Generates plugin API reference docsgenerator-joplin/ - Yeoman generator for scaffolding Joplin pluginshtmlpack/ - Packs HTML + assets into a single self-contained filelib/ - Core shared library: models, services, sync, e2ee, settings, shimonenote-converter/ - Converts OneNote notebooks to Joplin-compatible formatpdf-viewer/ - PDF viewer component used in desktop/mobileplugin-repo-cli/ - CLI for managing the Joplin plugin repositoryplugins/ - First-party plugins (backlinks, note tabs, rich markdown, etc.)react-native-alarm-notification/ - RN native module for alarm notificationsreact-native-saf-x/ - RN native module for Android Storage Access Frameworkrenderer/ - Markdown-to-HTML renderer (MathJax, Mermaid, highlight.js)server/ - Joplin Server (multi-user sync backend, REST API, Postgres/SQLite)tools/ - Build and release tooling scriptsSpin up an isolated sandbox and run it server-side — no local setup.
Tetrees AI Review of this version
This React web app completed archive review with strong static results. Structure, dependency manifests, documentation, functional source, and common risk patterns were checked by the Tetrees verification pipeline; runtime phases are stated separately.
Deterministic AVCP artifact review
Pipeline avcp-2026-08-04.1 · SHA-256 4db6a8880d5822ca…
This version-scoped review deterministically inspects the submitted archive for structure, dependencies, documentation, functional source, and common malicious or high-risk signals. Build and test phases are reported as passed only after an isolated sandbox audition. It is not a guarantee of perfect security.
Reviewed Aug 4, 2026
Push this product straight into your AI IDE, web builder or cloud IDE.
Connect Tetrees to a compatible AI IDE, list products you own, and request the verified ZIP without exposing seller upload controls.
No reviews yet.
Sign in to join the discussion
Loading discussion…
transcribe/turndown/ - HTML-to-Markdown converter (Joplin fork)turndown-plugin-gfm/ - GFM tables/strikethrough plugin for turndownutils/ - Shared utilities (Logger, path helpers, type guards)whisper-voice-typing/ - Whisper-based voice-to-text integrationnpm install compare-version sqlite3 fs-extra @electron/remote
npm install react react-redux redux
npm install @joplin/lib @joplin/utils @joplin/renderer
npm install electron # for desktop integration
npm install react-native # for mobile integration only
Native/additional build steps:
npm rebuild sqlite3 or use better-sqlite3 with the correct binding for your Node version.npm install sharp — if absent, a warning is printed but the CLI still runs.cd ios && pod install after adding React Native packages../gradlew linking; react-native-saf-x and react-native-alarm-notification require npx react-native link or manual build.gradle edits.app-desktop/package.json specifies to avoid native module ABI mismatch.source/ directory into your project root, e.g. ./joplin-packages/.tsconfig.json:
{
"compilerOptions": {
"paths": {
"@joplin/lib/*": ["./joplin-packages/lib/*"],
"@joplin/utils/*": ["./joplin-packages/utils/*"],
"@joplin/renderer/*": ["./joplin-packages/renderer/*"]
}
}
}
alias entries pointing to the same directories.import FsDriverNode from './joplin-packages/lib/fs-driver-node';
import shim from './joplin-packages/lib/shim';
// call shimInitNode or shimInitCli before any model usage
NODE_ENV=production # or 'dev' for dev app IDs
JOPLIN_PROFILE_DIR=/path/to/profile # where settings/db are stored
JOPLIN_BASE_URL, DB_CLIENT (pg or sqlite3), and MAILER_* vars as documented in server/.app (app-cli default export)// app-cli/app/app.ts
import app from './app';
// app is a singleton Application instance
app.start(argv: string[]): Promise<void>;
The CLI application singleton. Call app.start(process.argv) to boot the REPL, load the database, and register all commands. Used as the entry point in main.js.
ElectronAppWrapper (app-desktop)// app-desktop/ElectronAppWrapper.ts
import ElectronAppWrapper from './ElectronAppWrapper';
new ElectronAppWrapper(env: string, profileDir: string, isDebugMode: boolean): ElectronAppWrapper;
ElectronAppWrapper.prototype.start(): Promise<void>;
Wraps Electron's app lifecycle: creates the BrowserWindow, registers IPC handlers, and wires the bridge. Instantiated in main.ts after profile directory setup.
// app-desktop/commands/index.ts
import commands from './commands/index';
// commands: any[] — array of command module namespaces
// Each module exports: { execute(context): Promise<void>, declaration(): CommandDeclaration }
Auto-generated barrel of all desktop commands (copy, export, profile switching, external editor, etc.). Pass the array to the command service's registerCommands method to make them available via the command palette.
Embed the Joplin CLI inside a custom Node.js process, overriding the profile directory.
import FsDriverNode from './joplin-packages/lib/fs-driver-node';
import Logger from './joplin-packages/utils/Logger';
import app from './joplin-packages/app-cli/app/app';
import shimInitCli from './joplin-packages/app-cli/app/utils/shimInitCli';
async function main() {
const fsDriver = new FsDriverNode();
Logger.fsDriver_ = fsDriver;
await shimInitCli.default();
// Override argv to set a custom profile
const argv = ['node', 'main.js', '--profile', '/tmp/my-joplin-profile'];
await app.default.start(argv);
}
main().catch(console.error);
Load all built-in desktop commands and register them with a command service stub.
import commands from './joplin-packages/app-desktop/commands/index';
interface CommandDeclaration { name: string; label: string; }
interface CommandModule {
declaration(): CommandDeclaration;
execute(context: unknown): Promise<void>;
}
function registerCommands(mods: CommandModule[], context: unknown) {
for (const mod of mods) {
const decl = mod.declaration();
console.log(`Registering command: ${decl.name}`);
// wire into your command palette / IPC handler
}
}
registerCommands(commands as CommandModule[], { /* app context */ });
Start the desktop Electron application with a custom profile path.
// my-electron-main.ts
import { app as electronApp } from 'electron';
import ElectronAppWrapper from './joplin-packages/app-desktop/ElectronAppWrapper';
import FsDriverNode from './joplin-packages/lib/fs-driver-node';
import Logger from './joplin-packages/utils/Logger';
Logger.fsDriver_ = new FsDriverNode();
electronApp.whenReady().then(async () => {
const wrapper = new ElectronAppWrapper(
'prod', // env
'/home/user/.config/my-joplin', // profile dir
false // debug mode
);
await wrapper.start();
});
app-cli/ - Self-contained terminal client; app/app.ts is the singleton, app/main.js is the Node entry point that wires models and shim before handing off to app.start().app-clipper/ - Browser extension; content_scripts/index.js scrapes page DOM and popup/src/index.js provides the Redux-powered popup UI.app-desktop/ - Electron app; main.ts bootstraps the main process, ElectronAppWrapper manages window lifecycle, commands/index.ts is the auto-generated command barrel.app-mobile/ - React Native app for iOS/Android; contains native module bridges and RN-specific shim implementations.default-plugins/ - Pre-built plugin bundles copied into desktop distributions at build time.editor/ - CodeMirror 6 wrapper component used by both desktop and mobile editors.fork-htmlparser2/, fork-sax/, fork-uslug/ - Vendored and patched third-party parsers; import from here instead of upstream packages.lib/ - The heart of Joplin: ORM models (Note, Folder, Resource, etc.), sync engine, e2ee services, settings, and the platform shim interface.renderer/ - Converts Markdown to HTML with plugin support (math, diagrams, syntax highlighting); safe to use in Node or browser contexts.server/ - Express/Koa API server for self-hosted sync; has its own docker-compose setup and migration system.utils/ - Lightweight utilities (Logger, type helpers) shared across all packages with zero heavy dependencies.turndown/ + turndown-plugin-gfm/ - HTML→Markdown pipeline used by the web clipper and importer.npm rebuild sqlite3 --runtime=electron --target=<version> --dist-url=https://electronjs.org/headers.BaseItem.loadClass(...) calls must happen before any model is first accessed — copy the block from app-cli/app/main.js verbatim."type": "module" — if bundling with esbuild add --format=cjs or use dynamic import() at call sites.sharp not found warning flooding stdout: wrap require('sharp') in a try/catch and swallow the error as shown in main.js; the app remains functional.mkdirpSync(rootProfileDir) must be called before Setting.load() — missing this causes a silent DB open failure.app-desktop and app-mobile may pin different React majors — hoist a single version in your root package.json resolutions field.I have the Joplin monorepo packages available under `./source/` and the
integration guide at `./USAGE.md`. The upstream package is `joplin` (domain:
backend), source root `packages/`.
Please help me integrate the following into my existing Node.js/TypeScript
project step by step:
1. Read USAGE.md fully before writing any code.
2. Set up tsconfig paths and module aliases so that `@joplin/lib`,
`@joplin/utils`, and `@joplin/renderer` resolve to `./source/lib`,
`./source/utils`, and `./source/renderer` respectively.
3. Wire the FsDriverNode shim and Logger as shown in
`source/app-cli/app/main.js` before any model is imported.
4. Initialize the SQLite database and load Settings using the patterns
in `source/lib/`.
5. [Describe your specific feature here — e.g., "render a Markdown note
to HTML using source/renderer", "sync notes to a Joplin Server instance",
"import an Evernote ENEX file"].
6. Show the complete, runnable TypeScript code with real imports from
`./source/` only. Do not invent exports not present in USAGE.md.
Joplin is released under the MIT License. See source/ root or the upstream repository for the full license text.
Upstream project: https://github.com/laurent22/joplin
Upstream npm scope: @joplin/* (individual packages published separately under this scope).
This product’s unique contribution is clean room implementation of valuable code block into AVCP compatible standard.
The full install guide and integration prompts unlock after purchase.
Mobile App Templates & App Source Code
$10.02