BlockWriteAI
BlockWriteAI is a JSON-first block editor for web apps. It works with a script tag, npm, PHP/Composer, and Python static-file workflows.
Use the free core editor for normal documents. Serve premium tools such as AI, Mermaid, Drawing, Signature, and Signature Flow only through your licensed server endpoint.
Quick Start With Local Files
Add the stylesheet, editor script, and free plugin bundle:
<link rel="stylesheet" href="dist/blockwriteai.min.css">
<div id="editor"></div>
<script src="dist/blockwriteai.min.js"></script>
<script src="dist/plugins/blockwriteai-code-assist.min.js"></script>
<script src="dist/plugins/blockwriteai-advanced-blocks.min.js"></script>
<script>
const editor = new BlockWriteAI({
holder: "#editor",
placeholder: "Write something, or press / for blocks",
async onSave(data) {
await fetch("/api/documents", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
}
});
</script>Use these local files for production:
dist/blockwriteai.min.css
dist/blockwriteai.min.js
dist/plugins/blockwriteai-code-assist.min.js
dist/plugins/blockwriteai-advanced-blocks.min.js
Premium integrations should load licensed plugins and verify usage through the production BlockWriteAI Platform:
await BlockWriteAI.loadPremiumPlugins({
licenseKey: "bwai_live_xxxxx",
endpoint: BlockWriteAI.platformEndpoints.premiumPlugins,
features: ["drawing", "mermaid", "signature", "signature_flow", "ai"]
});Install With Node
npm install @blockwriteaileaf/blockwriteaiimport BlockWriteAI from "@blockwriteaileaf/blockwriteai";
import "@blockwriteaileaf/blockwriteai/css";
import "@blockwriteaileaf/blockwriteai/plugins/code-assist/min";
import "@blockwriteaileaf/blockwriteai/plugins/advanced/min";
const editor = new BlockWriteAI({
holder: "#editor",
premium: {
licenseKey: "bwai_live_xxxxx",
verifyEndpoint: BlockWriteAI.platformEndpoints.licenseVerify,
usageEndpoint: BlockWriteAI.platformEndpoints.aiUsage,
featureUsageEndpoint: BlockWriteAI.platformEndpoints.premiumUsage,
eventEndpoint: BlockWriteAI.platformEndpoints.premiumEvent,
signatureEventEndpoint: BlockWriteAI.platformEndpoints.signatureEvent
},
async onSave(data) {
await fetch("/api/documents", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
}
});Install With PHP
composer require qarakash/blockwriteaiPublish the package dist assets into a public asset directory in your app, then print the tags:
<?php
use QarAkash\BlockWriteAI\BlockWriteAIAssets;
echo BlockWriteAIAssets::stylesheetTag('/assets/blockwriteai');
echo BlockWriteAIAssets::scriptTags('/assets/blockwriteai');
$platform = BlockWriteAIAssets::platformEndpoints();
Create the editor:
<div id="editor"></div>
<script>
const editor = new BlockWriteAI({
holder: "#editor",
async onSave(data) {
await fetch("/api/documents/save.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
}
});
</script>Install With Python
pip install blockwriteai-editorCopy the packaged assets into your app static directory:
from blockwriteai_editor import copy_static
copy_static("static/blockwriteai")Generate tags in Flask, Django, or any Python web app:
from blockwriteai_editor import platform_endpoints, stylesheet_tag, script_tags
print(stylesheet_tag("/static/blockwriteai"))
print(script_tags("/static/blockwriteai"))
platform = platform_endpoints()Then mount the editor in your template:
<div id="editor"></div>
<script>
const editor = new BlockWriteAI({
holder: "#editor",
async onSave(data) {
await fetch("/api/documents", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
}
});
</script>Simple Persistence API
For most projects, store the full BlockWriteAI JSON document in your own database. Comments, replies, approvals, reject reasons, and document content stay inside the same JSON payload.
<div id="editor"></div>
<script>
const editor = new BlockWriteAI({
holder: "#editor",
documentId: "doc-123",
data: initialDocument,
persistence: {
localStorageKey: "rbe-demo-document",
async save({ documentId, data, type, action }) {
await fetch("/api/blockwriteai/document", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ documentId, data, type, action })
});
}
}
});
</script>Use the same adapter on preview pages. Set previewRuntime: true when you want preview-side comment approval, reject, reply, and signature actions to work without writing custom DOM patching code.
<div id="preview" class="blockwriteai-preview"></div>
<script>
BlockWriteAI.renderPreview("#preview", initialDocument, {
documentId: "doc-123",
previewRuntime: true,
persistence: {
localStorageKey: "rbe-demo-document",
async save({ documentId, data, type, action }) {
await fetch("/api/blockwriteai/document", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ documentId, data, type, action })
});
}
}
});
</script>For larger apps, split storage by feature:
persistence: {
save: ({ documentId, data }) => saveDocument(documentId, data),
comments: {
save: ({ documentId, comment, data }) => saveCommentTrail(documentId, comment, data)
},
signatures: {
save: ({ documentId, signatureType, signatureKey, signature }) => {
return saveSignature(documentId, signatureType, signatureKey, signature);
}
}
}Read Saved Documents
BlockWriteAI saves JSON. Store that JSON in your database, then render it later with a preview container:
<link rel="stylesheet" href="/assets/blockwriteai/blockwriteai.min.css">
<div class="blockwriteai-preview" data-source="/api/documents/123.json"></div>
<script src="/assets/blockwriteai/blockwriteai.min.js"></script>
<script src="/assets/blockwriteai/plugins/blockwriteai-advanced-blocks.min.js"></script>
<script>
BlockWriteAI.mountPreviews();
</script>The JSON endpoint can return a document directly:
{
"time": 1779540000000,
"version": "1.4.2",
"blocks": []
}It can also return a wrapper:
{
"ok": true,
"data": {
"time": 1779540000000,
"version": "1.4.2",
"blocks": []
}
}Premium Plugins
Do not expose premium plugin files as normal public scripts. Load them after your server verifies an active license:
<script>
async function bootEditor() {
await BlockWriteAI.loadPremiumPlugins({
licenseKey: "bwai_live_xxxxx",
endpoint: "https://blockwriteai.in/api/premium_plugins.php",
features: ["drawing", "mermaid", "signature", "signature_flow", "ai"]
});
window.editor = new BlockWriteAI({
holder: "#editor",
premium: {
licenseKey: "bwai_live_xxxxx",
verifyEndpoint: "https://blockwriteai.in/api/license_verify.php",
usageEndpoint: "https://blockwriteai.in/api/ai_usage.php"
},
ai: {
endpoint: "https://blockwriteai.in/api/ai_generate.php"
}
});
}
bootEditor();
</script>The browser plugin must never receive private API keys. Keep OpenAI, billing, usage limits, and license checks on your server.
Release Checklist
- Run
npm run build:min. - Run
npm run check. - Publish
@blockwriteaileaf/blockwriteaito npm. - Publish
qarakash/blockwriteaito Packagist. - Publish
blockwriteai-editorto PyPI. - Serve only the public asset directory from your application.
Notes For Production
- Use the
.min.cssand.min.jsfiles in public pages. - Do not publish source folders, examples, build artifacts, package caches, or private configuration files.
- Browser-delivered CSS and JavaScript can always be downloaded. Protect paid features with server-side license checks and metered premium bundle delivery.
- Keep secret keys in backend environment variables only.