open-pencil-cloud README

The project's README from github.com/yoohoo360/open-pencil-cloud. As one markdown file: README.md.

OpenPencil (Yoohoo fork)

A product fork of the open-source OpenPencil design editor. It keeps the upstream engine (.fig / .pen, CanvasKit rendering, SceneGraph) and adds a React shell, cloud documents, and internal deployment.

Upstream OpenPencil is under active development. This fork focuses on a React app shell and backend integration for business use.

Live preview → · Upstream demo · Upstream docs


Relationship to upstream OpenPencil

Upstream OpenPencil This fork (Yoohoo)
Focus Open-source editor + CLI / MCP / Vue SDK Productized editor on the same engine
App UI Vue 3 app under src/ Primary shell: packages/react
Backend Local-first, no required account Java server/ + cloud docs / OSS
Hosting Official web / desktop releases Static web app + Docker Compose API
Engine @open-pencil/core and related packages Same packages; product diffs prefer *.override.ts
License MIT MIT (upstream) + fork-owned config / deploy

Same: .fig I/O, SceneGraph, CanvasKit, Yoga layout, components/instances, and the programmable core.

Different: React product shell, cloud open/save, Aliyun OSS, and performance overrides (for example lazy .fig page load) without patching upstream sources in place.


Live preview

Environment URL
Dev preview http://pencil.dev.yoohoo.cn/
image image image

Local development

Requirements

Install

From the repo root:

bun install

Start the React editor

cd packages/react
bun run start
# NODE_ENV=development APP_ENV=local rspack server

Uses config.local.ts (API defaults to http://localhost:8080). Open http://localhost:8000.

Useful builds:

cd packages/react
bun run build:test   # APP_ENV=test (dev preview build)
bun run build:prod   # APP_ENV=prod

Start the API locally (optional)

Point Compose at a published image (adjust the tag as needed):

DATABASE_URL=jdbc:postgresql://xxx:5432/open-pencil
DATABASE_USERNAME=open-pencil
DATABASE_PASSWORD=xx
JWT_SECRET=your-super-secret-jwt-key-change-in-production-min-32-chars
SPRING_PROFILES_ACTIVE=dev

REDIS_HOST=xx
REDIS_PORT=xxx
REDIS_PASSWORD=xxx
REDIS_DATABASE=0

CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:1420,http://localhost:8000


JWT_EXPIRATION=8640000000
JWT_REFRESH_EXPIRATION=604800000


OAUTH_GITHUB_CLIENT_ID=xx
OAUTH_GITHUB_CLIENT_SECRET=xx
OAUTH_GOOGLE_CLIENT_ID=xx
OAUTH_GOOGLE_CLIENT_SECRET=xxx


# SMTP (leave MAIL_HOST empty to log verification codes in the API console)
MAIL_HOST=xxx
MAIL_PORT=xx
MAIL_USERNAME=xx
MAIL_PASSWORD=xx


# Storage: local / oss
STORAGE_TYPE=local

OSS_ENDPOINT=oss-cn-shanghai.aliyuncs.com
OSS_ACCESS_KEY=xx
OSS_SECRET_KEY=xx
OSS_BUCKET=xx
OSS_BASE_PATH=xx/
OSS_PRESIGN_EXPIRATION_SECONDS=900

cd server

Maven run Springboot

Without the API, the editor still opens local .fig files; cloud open/save needs the server (or a remote API URL in config).


Cloud deployment

Frontend (React static app)

Build and publish the packages/react dist (for example via .github/workflows/react-ui-deploy.yml), then serve it behind nginx. Dev preview: http://pencil.dev.yoohoo.cn/.

APP_ENV Config Typical use
local config.local.ts Local rspack
test config.dev.ts Dev preview site
prod config.prod.ts Production site

Backend (Docker Compose)

Run the API with Docker Compose on the host (same shape as local):

DATABASE_URL=jdbc:postgresql://xxx:5432/open-pencil
DATABASE_USERNAME=open-pencil
DATABASE_PASSWORD=xx
JWT_SECRET=your-super-secret-jwt-key-change-in-production-min-32-chars
SPRING_PROFILES_ACTIVE=dev

REDIS_HOST=xx
REDIS_PORT=xxx
REDIS_PASSWORD=xxx
REDIS_DATABASE=0

CORS_ALLOWED_ORIGINS=xxx,http://pencil.dev.yoohoo.cn


JWT_EXPIRATION=8640000000
JWT_REFRESH_EXPIRATION=604800000


OAUTH_GITHUB_CLIENT_ID=xx
OAUTH_GITHUB_CLIENT_SECRET=xx
OAUTH_GOOGLE_CLIENT_ID=xx
OAUTH_GOOGLE_CLIENT_SECRET=xxx


# SMTP (leave MAIL_HOST empty to log verification codes in the API console)
MAIL_HOST=xxx
MAIL_PORT=xx
MAIL_USERNAME=xx
MAIL_PASSWORD=xx


# Storage: local / oss
STORAGE_TYPE=oss

OSS_ENDPOINT=oss-cn-shanghai.aliyuncs.com
OSS_ACCESS_KEY=xx
OSS_SECRET_KEY=xx
OSS_BUCKET=yoohoo-oss
OSS_BASE_PATH=xx/
OSS_PRESIGN_EXPIRATION_SECONDS=900

services:
  open-pencil-server:
    image: registry.cn-hangzhou.aliyuncs.com/jongwong/open-pencil-server:0.0.1-beta.28
    container_name: open-pencil-server
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=dev
      - LOCAL_STORAGE_PATH=/app/storage
    volumes:
      - /data/docker-mnt/open-pencil-server/.env:/app/.env
      - /data/docker-mnt/open-pencil-server/storage:/app/storage
    restart: unless-stopped
    networks:
      - app-network

networks:
  app-network:
    external: true
# Ensure app-network exists, then:
docker compose pull open-pencil-server
docker compose up -d open-pencil-server

Update the image tag when releasing a new server build. Mount a real .env and persistent storage directory on the host. Use SPRING_PROFILES_ACTIVE=prod for production if that profile is configured in server/.

Image source: server/Dockerfile (multi-stage Maven → JRE).


Repository layout (excerpt)

packages/
  scene-graph/   graph model (may include index.override.ts)
  fig/           .fig parse / instances (*.override.ts)
  core/          engine / renderer / editor (performance overrides)
  react/         React product shell + cloud integration (primary app)
  cli/ mcp/ …    upstream programmable tooling
server/          cloud API (Java)

Prefer *.override.ts for product/engine diffs so upstream files stay mergeable; rspack remaps overrides at build time.


Upstream capabilities

Upstream still ships CLI (@open-pencil/cli), MCP, desktop AI agents, P2P collab, and token analysis. See:

This fork’s day-to-day path is the React shell + Compose API.


Checks

bun run check        # full gate
bun run test:unit    # unit tests
bun run format       # format

License

MIT License (upstream).

Upstream copyright belongs to OpenPencil contributors. Fork-owned React shell, cloud config, and deploy compose belong to this project’s maintainers.

open-pencil-cloud (yoohoo360/open-pencil-cloud)

Searching Database…

What is this?An AI-native, open-source Figma alternative: a product fork of the OpenPencil design editor. It keeps the upstream engine (.fig/.pen, CanvasKit rendering, SceneGraph) and adds a React shell, cloud documents, and internal deployment.
How is this fork different from the upstream OpenPencil editor?Upstream's UI is a Vue 3 app under src/; this fork's primary shell is React (packages/react) on the same engine, delivered as a static web app plus a Docker Compose API instead of upstream's official web and desktop releases.
How do I get it running locally?Install Bun, then from the repo root install dependencies and start the React editor, which uses config.local.ts. For the backend, cd server and run the Spring Boot API via Maven, or point Docker Compose at a published server image.
What do I need to have installed first?Bun (latest stable recommended) for the React app, plus optionally Docker to run the API via Compose. The backend is Java: a Spring Boot service built with Maven and shipped as a multi-stage Maven-to-JRE Docker image.
Does the editor still work if I skip the backend?Yes — without the API the editor still opens local .fig files. Only cloud open/save needs the server, or a remote API URL set in the config.
Is this built for solo designers or for teams?Teams and businesses: the fork adds cloud documents on Aliyun OSS and internal deployment for business use, while upstream remains a local-first editor with no required account.
Where can the whole thing be deployed?The frontend builds to a static React app served behind nginx (a react-ui-deploy GitHub Actions workflow is included), with per-environment configs for local, test, and prod. The backend runs on a host via Docker Compose with a real .env, a persistent storage directory, and the prod Spring profile.
Can I use it in commercial work?Yes — the code is MIT-licensed. Upstream engine code is copyrighted by OpenPencil contributors, while the fork's React shell, cloud config, and deploy compose belong to this fork's maintainers.
Why does this fork exist alongside upstream OpenPencil?It productizes the same engine for business use: a React shell instead of the Vue app, cloud open/save through a Java API with Aliyun OSS storage, and performance tweaks like lazy .fig page loading — all kept in override files so upstream sources stay untouched.
How do product tweaks avoid breaking upstream merges?Product and engine diffs prefer .override.ts files instead of patching upstream sources in place, and rspack remaps those overrides at build time, so upstream files stay mergeable.
What does the shared OpenPencil engine handle out of the box?The same engine as upstream: .fig and .pen file I/O, SceneGraph with CanvasKit rendering, Yoga layout, components and instances, and a programmable core. Upstream packages also ship a CLI (@open-pencil/cli), MCP, desktop AI agents, P2P collaboration, and token analysis.
Creator
yoohoo360
Size
48.4 MB
Stars
591
Updated
CommitOct 15
Age
6mo
Commits · 90 Days