{"_id":"@culturehq/editor-starter","_rev":"2-8dde7ee948224d19d943201a3c9a87c5","name":"@culturehq/editor-starter","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@culturehq/editor-starter","version":"1.0.0","_id":"@culturehq/editor-starter@1.0.0","maintainers":[{"name":"kddeisz","email":"kddnewton+npm@gmail.com"},{"name":"jsantamaria07","email":"josue@culturehq.com"}],"dist":{"shasum":"607e411d5077854e60973941a0ff02be39e4ef84","tarball":"https://registry.npmjs.org/@culturehq/editor-starter/-/editor-starter-1.0.0.tgz","fileCount":513,"integrity":"sha512-0VotGqjo/pALRN5IU0ARkFgGMePU4rpfXs8T7gNp9MLLeiDi5CJ9UojQXoclf/DpMZlyTR0zkyqEo9Q+axYMvQ==","signatures":[{"sig":"MEQCIDX6+UPHmr78GVfLqVHVA7vxHiWjwQJ1NnzhI5JokIFkAiBdpqkGfrtmg83EiaNHn0UFStg7se3UYgtLrqKkTQdV8w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":5492313},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"b3424f01ac4814b6cd4e31499b0640bdaa7f7732","private":false,"scripts":{"dev":"react-router dev","lint":"eslint . && prettier --write .","build":"npm run typecheck:build && (tsx deploy.ts || true) && react-router build ","start":"react-router-serve ./build/server/index.js","upgrade":"remotion upgrade","typecheck":"react-router typegen && tsc","build:package":"vite build --config vite.config.package.ts","deploy:vercel":"bash scripts/deploy-vercel.sh","deploy:railway":"bash scripts/deploy-railway.sh","prepublishOnly":"npm run build:package","remotion:bundle":"remotion bundle","remotion:studio":"remotion studio","typecheck:build":"react-router typegen && tsc --noEmit","remotion:upgrade":"remotion upgrade"},"_npmUser":{"name":"jsantamaria07","email":"josue@culturehq.com"},"_npmVersion":"10.8.2","description":"![Editor Starter Screenshot](https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/editor-starter-og-image.jpg)","directories":{},"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"packageManager":"npm","devDependencies":{"tsx":"^4.21.0","zod":"^3.24.3","vite":"7.2.6","isbot":"^5","react":"^19.2.3","dotenv":"^17.2.3","eslint":"9.31.0","openai":"^4.67.3","sonner":"^2.0.7","postcss":"^8","prettier":"^3.5.3","remotion":"4.0.386","react-dom":"^19.2.3","assemblyai":"^4.22.0","mediabunny":"1.25.8","typescript":"^5","@types/node":"^20","tailwindcss":"^4.1.3","@types/react":"^19","react-router":"^7.7.1","@remotion/cli":"4.0.386","@remotion/gif":"4.0.386","@remotion/media":"4.0.386","vite-plugin-dts":"^4.0.0","@remotion/lambda":"4.0.386","@remotion/player":"4.0.386","@remotion/shapes":"4.0.386","@types/react-dom":"^19","@react-router/dev":"^7.7.1","@tailwindcss/vite":"^4.1.4","@aws-sdk/client-s3":"^3.953.0","@react-router/node":"^7.7.1","@remotion/captions":"4.0.386","@react-router/serve":"^7.7.1","@tailwindcss/postcss":"^4.1.3","@vercel/react-router":"^1.1.0","@vitejs/plugin-react":"^4.0.0","@radix-ui/react-select":"^2.2.5","@remotion/google-fonts":"4.0.386","@remotion/layout-utils":"4.0.386","@remotion/media-parser":"4.0.386","@radix-ui/react-popover":"^1.1.14","@tanstack/react-virtual":"^3.13.10","@remotion/openai-whisper":"4.0.386","@remotion/rounded-text-box":"4.0.386","prettier-plugin-tailwindcss":"^0.6.11","@radix-ui/react-context-menu":"^2.2.15","@remotion/eslint-config-flat":"4.0.386","@aws-sdk/s3-request-presigner":"^3.787.0","prettier-plugin-organize-imports":"^4.1.0"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0","sonner":"^2.0.0","remotion":"^4.0.0","react-dom":"^18.0.0 || ^19.0.0","@remotion/gif":"^4.0.0","@remotion/media":"^4.0.0","@remotion/player":"^4.0.0","@remotion/shapes":"^4.0.0","@remotion/captions":"^4.0.0","@radix-ui/react-select":"^2.0.0","@remotion/google-fonts":"^4.0.0","@remotion/layout-utils":"^4.0.0","@radix-ui/react-popover":"^1.0.0","@tanstack/react-virtual":"^3.0.0","@remotion/rounded-text-box":"^4.0.0","@radix-ui/react-context-menu":"^2.0.0"},"peerDependenciesMeta":{"sonner":{"optional":true},"@radix-ui/react-select":{"optional":true},"@radix-ui/react-popover":{"optional":true},"@tanstack/react-virtual":{"optional":true},"@radix-ui/react-context-menu":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/editor-starter_1.0.0_1766396498314_0.12874789761376704","host":"s3://npm-registry-packages-npm-production"},"deprecated":"This package has been removed."}},"time":{"created":"2025-12-22T09:41:38.207Z","modified":"2025-12-23T12:45:40.844Z","1.0.0":"2025-12-22T09:41:38.527Z"},"description":"![Editor Starter Screenshot](https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/editor-starter-og-image.jpg)","maintainers":[{"name":"jsantamaria07","email":"josue@culturehq.com"},{"name":"kddeisz","email":"kddnewton+npm@gmail.com"}],"readme":"![Editor Starter Screenshot](https://pub-646d808d9cb240cea53bedc76dd3cd0c.r2.dev/editor-starter-og-image.jpg)\n\nA reusable NPM package containing the most essential elements of a video editor.\n\n- **Save countless hours** by leveraging our pre-made components for timeline, interactive canvas, font picker, asset uploads, etc.\n- **Get the best of Remotion** put together into one template, culminating years of development and battle-testing.\n- **Customize anything** by adopting a clean, well-structured codebase with 80+ feature flags.\n- **Easy integration** - Install as an NPM package and use in your React applications.\n\n## Installation\n\n```bash\nnpm install @brianvigeant/editor-starter\n```\n\n## Quick Start\n\n```tsx\nimport {Editor} from '@brianvigeant/editor-starter';\nimport type {\n  EditorApiConfig,\n  EditorCallbacks,\n} from '@brianvigeant/editor-starter';\n\nfunction App() {\n  const apiConfig: EditorApiConfig = {\n    uploadUrl: '/api/upload',\n    renderUrl: '/api/render',\n    captionsUrl: '/api/captions',\n    progressUrl: '/api/progress',\n  };\n\n  const callbacks: EditorCallbacks = {\n    onRenderComplete: (output) => {\n      console.log('Video URL:', output.videoUrl);\n      console.log('State:', output.state);\n      console.log('Captions:', output.captions);\n      // Download the video or handle it as needed\n    },\n    onRenderError: (error) => {\n      console.error('Render error:', error);\n    },\n    onStateChange: (state) => {\n      // Optional: Save state periodically\n      console.log('State changed');\n    },\n  };\n\n  return (\n    <div style={{width: '100vw', height: '100vh'}}>\n      <Editor apiConfig={apiConfig} callbacks={callbacks} />\n    </div>\n  );\n}\n```\n\n## API Configuration\n\nThe Editor requires API endpoints for various operations. You must provide your own backend endpoints:\n\n- **uploadUrl**: Endpoint for uploading assets (videos, images, audio, etc.)\n- **renderUrl**: Endpoint for triggering video rendering\n- **captionsUrl**: Endpoint for generating captions from audio/video\n- **progressUrl**: Endpoint for checking render progress\n\n### API Endpoint Requirements\n\n#### Upload Endpoint (`uploadUrl`)\n\n**Request:**\n\n```json\nPOST /api/upload\nContent-Type: application/json\n\n{\n  \"contentType\": \"video/mp4\",\n  \"size\": 1234567\n}\n```\n\n**Response:**\n\n```json\n{\n  \"presignedUrl\": \"https://...\",\n  \"fileKey\": \"videos/abc123.mp4\",\n  \"readUrl\": \"https://...\"\n}\n```\n\n#### Render Endpoint (`renderUrl`)\n\n**Request:**\n\n```json\nPOST /api/render\nContent-Type: application/json\n\n{\n  \"compositionHeight\": 1080,\n  \"compositionWidth\": 1920,\n  \"tracks\": [...],\n  \"items\": {...},\n  \"assets\": {...},\n  \"codec\": \"h264\"\n}\n```\n\n**Response:**\n\n```json\n{\n  \"type\": \"success\",\n  \"bucketName\": \"my-bucket\",\n  \"renderId\": \"render-123\"\n}\n```\n\n#### Progress Endpoint (`progressUrl`)\n\n**Request:**\n\n```json\nPOST /api/progress\nContent-Type: application/json\n\n{\n  \"bucketName\": \"my-bucket\",\n  \"renderId\": \"render-123\"\n}\n```\n\n**Response:**\n\n```json\n{\n  \"type\": \"done\",\n  \"outputFile\": \"https://.../video.mp4\",\n  \"outputSizeInBytes\": 1234567,\n  \"outputName\": \"video.mp4\"\n}\n```\n\n#### Captions Endpoint (`captionsUrl`)\n\n**Request:**\n\n```json\nPOST /api/captions\nContent-Type: application/json\n\n{\n  \"fileKey\": \"audio/abc123.wav\",\n  \"readUrl\": \"https://...\"\n}\n```\n\n**Response:**\n\n```json\n{\n  \"captions\": [\n    {\n      \"text\": \"Hello world\",\n      \"start\": 0,\n      \"end\": 2.5\n    }\n  ]\n}\n```\n\n## Loading Initial State\n\nYou can load an existing project by providing initial state:\n\n```tsx\nimport type { UndoableState } from '@brianvigeant/editor-starter';\n\nconst initialState: UndoableState = {\n  tracks: [...],\n  items: {...},\n  assets: {...},\n  fps: 30,\n  compositionWidth: 1920,\n  compositionHeight: 1080,\n  deletedAssets: [],\n};\n\n// For assets with URLs\n<Editor initialState={initialState} />\n\n// For assets with blob files (provide separately)\n<Editor\n  initialState={initialState}\n  initialBlobs={{\n    \"asset-123\": blobFile,\n    \"asset-456\": anotherBlobFile,\n  }}\n/>\n```\n\n**Note:** Assets in the initial state JSON can have `remoteUrl` for URL-based assets, or `remoteUrl: null` for blob-based assets (which must be provided via `initialBlobs` prop).\n\n## Output Format\n\nWhen rendering completes, the `onRenderComplete` callback receives:\n\n```typescript\n{\n  videoUrl: string;        // URL to download the rendered MP4\n  state: UndoableState;   // Complete editor state that generated the video\n  captions: Caption[];     // Extracted captions from CaptionAsset items\n}\n```\n\nThe `state` object contains the complete `UndoableState` with:\n\n- `tracks`: Array of timeline tracks\n- `items`: Record of all editor items (videos, text, captions, etc.)\n- `assets`: Record of all assets (preserves `remoteUrl` structure)\n- `fps`: Frames per second\n- `compositionWidth`: Composition width\n- `compositionHeight`: Composition height\n\n**Important:** The package provides the video URL only - you must handle downloading the MP4 file yourself.\n\n## Remotion Lambda Setup\n\n**Important:** You are responsible for setting up and deploying Remotion Lambda separately. The package uses your Remotion Lambda setup via the render API endpoint. See [Remotion Lambda documentation](https://www.remotion.dev/docs/lambda) for setup instructions.\n\n## State Export Utilities\n\nExport the current editor state:\n\n```tsx\nimport {\n  exportStateAsJson,\n  exportStateAsBlob,\n  downloadStateAsJson,\n} from '@brianvigeant/editor-starter';\n\n// Get state from onStateChange callback or onRenderComplete\nconst jsonString = exportStateAsJson(state);\nconst blob = exportStateAsBlob(state);\ndownloadStateAsJson(state, 'my-project.json');\n```\n\n## Integration with External Projects\n\nThis package can be integrated into other projects while maintaining the ability to receive frequent updates.\n\n**Using Git:**\n\n```json\n{\n  \"dependencies\": {\n    \"@brianvigeant/editor-starter\": \"git+https://github.com/brianvigeant/editor-starter.git#main\"\n  }\n}\n```\n\nSee [INTEGRATION.md](./INTEGRATION.md) for detailed integration guide.\n\n## Resources\n\n### This Fork\n\n- 📖 [Integration Guide](./INTEGRATION.md) - How to integrate with external projects\n- 🎨 [CSS Scoping Guide](./CSS_SCOPING.md) - CSS isolation best practices\n- 🔄 [Upstream Updates](./UPSTREAM_UPDATES.md) - Keeping up-to-date with remotion-dev/editor-starter\n\n### Official Documentation\n\n- 📚 [Documentation](https://www.remotion.dev/docs/editor-starter)\n  - [Setup](https://www.remotion.dev/docs/editor-starter/setup)\n  - [Dependencies](https://www.remotion.dev/docs/editor-starter/dependencies)\n  - [Features](https://www.remotion.dev/docs/editor-starter/features)\n  - [State Management](https://www.remotion.dev/docs/editor-starter/state-management)\n  - [Tracks, Items and Assets](https://www.remotion.dev/docs/editor-starter/tracks-items-assets)\n  - [Undo and Redo](https://www.remotion.dev/docs/editor-starter/undo-redo)\n  - [Copy and Paste](https://www.remotion.dev/docs/editor-starter/copy-paste)\n  - [Cropping](https://www.remotion.dev/docs/editor-starter/cropping)\n  - [Fonts](https://www.remotion.dev/docs/editor-starter/fonts)\n  - [Asset uploads](https://www.remotion.dev/docs/editor-starter/asset-uploads)\n  - [Asset cleanup](https://www.remotion.dev/docs/editor-starter/asset-cleanup)\n  - [Persistance](https://www.remotion.dev/docs/editor-starter/persistance)\n  - [Captions](https://www.remotion.dev/docs/editor-starter/captioning)\n  - [Rendering](https://www.remotion.dev/docs/editor-starter/rendering)\n  - [Backend routes](https://www.remotion.dev/docs/editor-starter/backend-routes)\n  - [Production Checklist](https://www.remotion.dev/docs/editor-starter/production-checklist)\n  - [Features not included](https://www.remotion.dev/docs/editor-starter/features-not-included)\n  - [FAQ](https://www.remotion.dev/docs/editor-starter/faq)\n- 🎞️ [Demo](https://editor-starter.remotion.dev/)\n- 🛒 [Store page](https://remotion.pro/editor-starter)\n- 👾 [Discord community](https://remotion.dev/discord)\n- 📄 [License](/LICENSE.md)\n","readmeFilename":"README.md"}