Skip to content
WoffluonPublic

About

Lightweight, self-hosted inline text editing for React and Next.js. Lets teams edit copy directly on the page without touching code or layouts.

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

CopyPatch

Modern, same-origin inline copy editor for React applications.

CI Status Version License Node Documentation

English | Türkçe

CopyPatch

CopyPatch gives teams and clients the ability to edit production copy directly on the page without touching code or opening a separate CMS.

Mark editable strings with React components, mount the embedded backend inside your host application, and let authorized editors update content on-demand by appending ?copypatch=1 to any URL.


Documentation portal

Category Destination Description
Core & React @copypatch/core
@copypatch/react
Shared types, contracts, <EditableText>, <CopyPatchProvider>, and editor overlay.
Backend & Node @copypatch/backend
@copypatch/node
Storage-independent HTTP controller, Express/Fastify/Hono adapters, and project CLI.
Persistence @copypatch/storage-sqlite
@copypatch/storage-postgres
SQLite (single-node) and PostgreSQL (distributed horizontal clusters) adapters.
Next.js @copypatch/next Next.js App Router route handlers, server snapshot pre-fetching, and provider wrappers.
Architecture docs/architecture.md Runtime shape, boundaries, data flow, and documentation governance.
Security docs/threat-model.md
SECURITY.md
Threat boundary, authentication, CSRF, and disclosure policy.
Examples examples/ Runnable reference integrations for Next.js, Astro, React Router, and Vite.
Documentation site English docs
Türkçe dokümanlar
Framework guides, API reference, operations, and local full-text search.

Architecture at a glance

CopyPatch runs embedded inside your application runtime. It does not require a standalone API server, additional open ports, reverse proxies, or external CORS configuration:

flowchart LR
  Browser["Browser (?copypatch=1)"] --> Host["Host application"]
  Host --> ReactView["React components (<EditableText>)"]
  Host --> ApiRoute["API route (/__copypatch/api/v2/*)"]
  ApiRoute --> Backend["@copypatch/backend"]
  Backend --> Storage["SQLite / PostgreSQL"]
Loading

Key Architectural Pillars

  • Same-origin deployment: The API route mounts directly under /__copypatch/api/v2. All network requests stay on the origin, removing CORS configuration and external attack vectors.
  • Zero visitor bundle bloat: Public visitors receive only lightweight React text tags. The visual editor, diff views, and authentication modals load dynamically only when ?copypatch=1 is requested.
  • Server snapshot rendering: Server components (RSC) and SSR routes read published copy directly from the backend, avoiding layout shifts and client hydration waterfalls.
  • Revision coordination: Built-in atomic compare-and-swap mechanics prevent draft overwrites and race conditions during concurrent editing sessions.

Quick start

1. Install packages

pnpm add @copypatch/core @copypatch/react @copypatch/backend @copypatch/storage-sqlite @copypatch/node @copypatch/next

Public packages other than @copypatch/storage-sqlite support Node.js >=20. The SQLite adapter matches the narrower native-runtime range of better-sqlite3@12: Node.js 20.x, 22.x, 23.x, 24.x, 25.x, or 26.x. @copypatch/storage-sqlite does not support Node.js 21.

2. Wrap your layout and tag editable copy

import { NextCopyPatchProvider, EditableText } from '@copypatch/next';
import { readPublishedSnapshot } from '@copypatch/next/server';
import { backend } from '@/lib/copypatch';

export default async function Layout({ children }: { children: React.ReactNode }) {
  const snapshot = await readPublishedSnapshot(backend, 'en');

  return (
    <NextCopyPatchProvider locale="en" initialSnapshot={snapshot}>
      <header>
        <EditableText contentKey="header.title" as="h1">
          Welcome to our product
        </EditableText>
      </header>
      <main>{children}</main>
    </NextCopyPatchProvider>
  );
}

3. Open the inline editor

Navigate to any page with ?copypatch=1 (for example, http://localhost:3000/?copypatch=1). Authenticate with your configured passphrase, edit copy directly on the page, and save drafts or publish changes instantly.

Monorepo packages

All public packages publish in lockstep versioning (3.0.2):

Package Version Description Readme
@copypatch/core 3.0.2 Shared contracts, constants, schemas, and persistence interfaces. README
@copypatch/react 3.0.2 Provider, hooks, <EditableText>, and on-demand editor runtime. README
@copypatch/backend 3.0.2 Storage-agnostic HTTP handler, auth contract, and mutation engine. README
@copypatch/storage-sqlite 3.0.2 SQLite adapter for single-node and local deployments. README
@copypatch/storage-postgres 3.0.2 PostgreSQL adapter for horizontal multi-instance clusters. README
@copypatch/node 3.0.2 Adapters for Express, Fastify, Hono, Node HTTP, and copypatch CLI. README
@copypatch/next 3.0.2 Next.js App Router route handlers, RSC snapshot readers, and provider. README

Choose your framework

CopyPatch provides tested, production-grade example implementations for major frameworks:


CLI quick reference

The @copypatch/node package includes the copypatch CLI utility:

# Scaffold initial configuration and route mounts
pnpm exec copypatch init --framework next --storage sqlite

# Generate an Argon2id passphrase hash securely from stdin
printf 'your-secure-passphrase' | pnpm exec copypatch hash --stdin

# Inspect the generated configuration and CopyPatch environment variables
pnpm exec copypatch doctor

Security and access control

  • Passphrase Authentication: Built-in Argon2id password hashing with time-safe verification.
  • Session Cookies: HTTP-only, secure, SameSite cookies hold high-entropy tokens; persistence stores token hashes rather than raw tokens.
  • CSRF Defense: Mutation requests require the x-copypatch-csrf header matching the active session.
  • Role Hierarchy: Enforces editor (save and discard drafts) and publisher (promote drafts to live copy) permissions.
  • Custom Auth Adapters: Integrate with existing session stores (NextAuth, Clerk, Lucia, Supabase) via custom auth adapters.

See the full Threat Model and Security Policy for details.


Contributing and release workflow

We welcome contributions! Please review CONTRIBUTING.md for repository guidelines and local setup instructions.

pnpm install --frozen-lockfile   # Install dependencies
pnpm build                      # Build all packages
pnpm typecheck                  # Validate TypeScript across all packages
pnpm test                       # Run Vitest suite and release contracts
pnpm test:e2e                   # Run Playwright E2E browser tests

Conventional Commits & Lockstep Releases

All versioned changes follow the lockstep release policy. Prepare commits using:

pnpm release:prepare -- "feat: describe your feature"

License

MIT License. See LICENSE for details.

About

Lightweight, self-hosted inline text editing for React and Next.js. Lets teams edit copy directly on the page without touching code or layouts.

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages