pinme
PinMe is a zero-config deployment tool that uploads static files to IPFS or deploys full-stack web projects combining React+Vite frontends with Cloudflare Workers backends and D1 databases. Use it when users need file uploads, IPFS storage, website publishing, or full-stack services requiring backend APIs, database storage, or email functionality through the PinMe platform API.
git clone --depth 1 https://github.com/glitternetwork/pinme /tmp/pinme && cp -r /tmp/pinme/skills/pinme ~/.claude/skills/pinmeSKILL.md
# PinMe
Zero-config deployment tool: upload static files to IPFS, or create and deploy full-stack web projects (React+Vite + Cloudflare Worker + D1 database). Workers also support sending emails via the PinMe platform API.
## When to Use
```dot
digraph pinme_decision {
"User Request" [shape=doublecircle];
"Needs backend API or database?" [shape=diamond];
"Upload Files (Path 1)" [shape=box];
"Full-Stack Project (Path 2)" [shape=box];
"User Request" -> "Needs backend API or database?";
"Needs backend API or database?" -> "Upload Files (Path 1)" [label="No"];
"Needs backend API or database?" -> "Full-Stack Project (Path 2)" [label="Yes"];
}
```
## Path 1: Upload Files / Static Sites
> Login required. Use `pinme login` or `pinme set-appkey <AppKey>` before `pinme upload` or `pinme import`.
```dot
digraph upload_flow {
"Install/update pinme to latest" [shape=box];
"Authenticate" [shape=box];
"Determine build artifacts" [shape=box];
"pinme upload <path>" [shape=box];
"Return preview URL" [shape=doublecircle];
"Install/update pinme to latest" -> "Authenticate";
"Authenticate" -> "Determine build artifacts";
"Determine build artifacts" -> "pinme upload <path>";
"pinme upload <path>" -> "Return preview URL";
}
```
**1. Check installation and update to latest:**
```bash
LOCAL=$(pinme --version 2>/dev/null || echo "0.0.0")
LATEST=$(npm view pinme version)
[ "$LOCAL" != "$LATEST" ] && npm install -g pinme@latest || echo "pinme is up to date ($LOCAL)"
```
**2. Authenticate:**
```bash
pinme login
# or: pinme set-appkey <AppKey>
```
**3. Determine upload target** (priority order):
1. `dist/` — Vite / Vue / React
2. `build/` — Create React App
3. `out/` — Next.js static export
4. `public/` — Plain static files
**4. Upload:**
```bash
pinme upload <path>
pinme upload ./dist --domain my-site # Optional: bind subdomain (wallet balance required)
```
**5. Return** the final URL printed by PinMe to the user. URL priority is: DNS domain > PinMe subdomain > short URL > preview URL. If it falls back to preview, return the **full URL** including all hash characters — do not truncate.
### Common Examples
```bash
pinme upload ./document.pdf # Single file
pinme upload ./my-folder # Folder
pinme upload dist # Vite/Vue build artifacts
pinme upload build # CRA build artifacts
pinme upload out # Next.js static export
pinme upload ./dist --domain my-site # Bind PinMe subdomain (wallet balance required)
pinme import ./my-archive.car # Import CAR file
```
### Do NOT Upload
- `node_modules/`, `.env`, `.git/`, `src/`
- Only upload build artifacts, never upload source code
---
## Path 2: Full-Stack Project
> Login required. Uses React+Vite frontend + Cloudflare Worker backend + D1 SQLite database.
> When designing frontend projects, use Ant Design as the primary design reference, and prioritize following its conventions for layout, components, spacing, and interaction patterns.
```dot
digraph fullstack_flow {
"Install/update pinme to latest" [shape=box];
"pinme login" [shape=box];
"pinme create <name>" [shape=box];
"Modify template code" [shape=box];
"pinme save" [shape=box];
"Return preview URL" [shape=doublecircle];
"Install/update pinme to latest" -> "pinme login";
"pinme login" -> "pinme create <name>";
"pinme create <name>" -> "Modify template code";
"Modify template code" -> "pinme save";
"pinme save" -> "Return preview URL";
}
```
### Architecture
| Layer | Tech Stack | Deploy Target |
|-------|-----------|---------------|
| Frontend | React + Vite (`frontend/`) | IPFS |
| Backend | Cloudflare Worker (`backend/src/worker.ts`) | `{name}.pinme.pro` |
| Database | D1 SQLite (`db/*.sql`) | Cloudflare D1 |
### Core Commands
```bash
pinme login # Login (only needed once)
pinme create <dirName> # Clone template and create project (auto-fills API URL)
pinme save # First deploy / full update (frontend + backend + database, single command)
pinme update-worker # Update backend only (when only backend/src/worker.ts was modified)
pinme update-web # Update frontend only (when only frontend/src/ was modified)
pinme update-db # Run SQL migrations only (when only db/ was modified)
```
> `pinme save` deploys frontend + backend + database all at once. Only use `pinme update-*` when you're certain only one part was modified.
### Project Structure
```
{project}/
├── pinme.toml # Root config (auto-generated, do not modify)
├── package.json # Monorepo root (workspaces: frontend + backend)
├── backend/
│ ├── wrangler.toml # Worker config (auto-generated, do not modify)
│ ├── package.json
│ └── src/
│ └── worker.ts # Backend entry — primarily used for JSON APIs in this template
├── db/
│ └── 001_init.sql # SQL table definitions
├── frontend/
│ ├── package.json
│ ├── vite.config.ts # Dev proxy: /api → localhost:8787
│ ├── index.html
│ ├── .env # Auto-generated: VITE_API_URL (do not modify)
│ └── src/
│ ├── main.tsx
│ ├── App.tsx
│ ├── utils/
│ │ ├── api.ts # export const API = import.meta.env.VITE_WORKER_URL || ''
│ │ └── config.ts # Auto-generated: public_client_config (only when auth is enabled)
│ └── pages/
│ └── Home/
│ └── index.tsx
└── .gitignore
```
### First Deployment
```bash
LOCAL=$(pinme --version 2>/dev/null || echo "0.0.0")
LATEST=$(npm view pinme version)
[ "$LOCAL" != "$LATEST" ] && npm install -g pinme@latest
pinme login
pinme create my-app
cd my-app
```
`pinme create` generates a working Hello World template (includes frontend page + backend API routes + database schema). **Modify the template** to match the user's business logic — do not write from scratch:
- Modify `backend/sUse when a PinMe project (Worker TypeScript) needs to integrate user authentication — creating email/password users, verifying id_tokens, querying user info, or listing users via Identity Platform auth proxy APIs.
Use this skill when a PinMe project (Worker TypeScript) needs to integrate email sending (send_email). Guides AI to generate correct Worker TS code.
Use this skill when a PinMe project (Worker TypeScript) needs to call OpenRouter-backed LLM APIs, including models, chat/completions, streaming, or OpenRouter web search. Guides AI to generate correct Worker TS code.
Use this skill when the user wants to share, publish, or upload a static result through PinMe, especially by generating a static HTML share page for a PinMe project link, deployed full-stack app, Codex conversation summary, report, file, demo, or any 分享/发布/上传分享页 request that should end with `pinme upload`.