A web app for creating and animating ASCII/ANSI art.
Current deployed version: https://ascii-motion.app
See what people are making in the community gallery: https://ascii-motion.app/community
Learn more on the landing page: https://ascii-motion.com
Check the usage documentation at: https://docs.ascii-motion.com
- Grid-based ASCII Art Editor with full drawing toolset (pencil, eraser, fill, rectangle, ellipse, bezier pen, text, gradient, and more)
- Convert images or video assets to ASCII art with fine-tuned rendering control and frame rate matching
- Custom Color and Character Palettes including presets and import/export
- Apply effects and filters to existing animations
- Generate animations using procedural animation tools
- Layer-Based Timeline with keyframe interpolation for position, scale, rotation, and anchor point
- Multi-Layer Compositing with z-order, visibility, solo, lock, and layer groups
- Keyframe Animation with cubic bezier easing editor and presets
- Export Formats: Images (PNG, JPEG, SVG), Videos (MP4, WebM), React Components, CLI Components (Ink, OpenTUI, BubbleTea), Text, HTML, and session files
- Publish to community gallery and explore what people are making
- MCP Server (ascii-motion-mcp) for AI-assisted animation creation
- Node.js 18+
- npm or yarn
git clone https://github.com/cameronfoxly/Ascii-Motion.git
cd Ascii-Motion
npm installnpm run devnpm run buildThis monorepo contains three separate deployable apps, each with its own Vercel project:
| App | Domain | Deploy From | Command |
|---|---|---|---|
| Main App | ascii-motion.app |
Root | npm run deploy |
| Marketing | ascii-motion.com |
packages/web/marketing |
npx vercel --prod |
| Docs | docs.ascii-motion.com |
packages/web/docs-site |
npx vercel --prod |
The main ASCII art editor deploys with automated versioning:
Available Deployment Commands
| Command | Version Increment | Use Case |
|---|---|---|
npm run deploy |
Patch (2.0.0 β 2.0.1) | Bug fixes, small updates |
npm run deploy:major |
Minor (2.0.1 β 2.1.0) | New features, significant improvements |
npm run deploy:preview |
None | Testing deployments, preview branches |
For version management without deployment:
# Increment patch version (2.0.0 β 2.0.1)
npm run version:patch
# Increment minor version (2.0.1 β 2.1.0)
npm run version:minor
# Increment major version (2.1.0 β 3.0.0)
npm run version:majorThese deploy separately from the main app using the Vercel CLI:
# Marketing site (ascii-motion.com)
cd packages/web/marketing
npx vercel --prod
# Docs site (docs.ascii-motion.com)
cd packages/web/docs-site
npx vercel --prodSee the README in each package for detailed deployment instructions.
- React 19 - UI framework
- TypeScript - Type safety (strict mode)
- Vite - Build tool and dev server
- Tailwind CSS v3 - Styling
- Shadcn/ui - UI components
- Zustand - State management
- Lucide React - Icons
- Vitest - Testing framework
This is a monorepo with dual licensing and separate deployment targets:
-
packages/core/- Open source core features (MIT License)- Canvas editor, drawing tools, animation system
- Export features (PNG, SVG, GIF, MP4, etc.)
- All UI components and utilities
-
packages/premium/- Premium features (Proprietary License)- User authentication (email-based)
- Cloud project storage (Supabase)
- Payment integration (future)
-
packages/web/marketing/- Marketing site (Proprietary License)- Deploys to
ascii-motion.com - Next.js 16 + React 19
- Has its own
package.jsonand Vercel project
- Deploys to
-
packages/web/docs-site/- Documentation site (Proprietary License)- Deploys to
docs.ascii-motion.com - Next.js 15 + MDX
- Has its own
package.jsonand Vercel project
- Deploys to
See docs/MONOREPO_SETUP_GUIDE.md for details.
src/
βββ components/
β βββ common/ # Shared/reusable components
β βββ features/ # Complex functional components (canvas, import/export)
β β βββ timeline/ # Layer list, track area, keyframe editor, ruler
β βββ tools/ # Tool-specific components
β βββ ui/ # Shadcn UI components
βββ stores/
β βββ timelineStore.ts # PRIMARY: layers, content frames, keyframes, groups
β βββ canvasStore.ts # Working canvas buffer for active layer
β βββ animationStore.ts # Legacy compatibility adapter
β βββ toolStore.ts # Tools, settings, undo/redo history
βββ types/
β βββ timeline.ts # Layer, ContentFrame, Keyframe, PropertyTrack types
β βββ easing.ts # Cubic bezier interpolation engine
βββ hooks/ # Custom React hooks
βββ utils/
β βββ layerCompositing.ts # Multi-layer compositing with transforms
β βββ layerTransformUtils.ts # Screenβlocal coordinate conversion
β βββ sessionMigration.ts # v1βv2 format migration
βββ constants/ # App configuration
βββ pages/ # Page components
This is currently maintained entirely by me, an animator and brand designer with next to no prior experience with building tools. This has been meticulously vibe-coded into existence over the last year or so, starting with GitHub Copilot in VScode and Claude Opus 4.6. More recently I've been using auto model mode in the GitHub Copilot App, and probably wont go back to a traditional IDE. Please forgive any messy or unusal structure or vibe-code artifacts, I'm trying my best!
I've made it through my backlog of features. Got an idea for a new feature? Open an issue!
- Copilot Instructions - Architecture overview and development guidelines
- Contributing Guide - How to contribute
- Monorepo Setup Guide - Dual-license structure
- Layer Timeline Refactor Plan - v2.0.0 architecture design
- Technical Documentation - Implementation guides and feature documentation. Each .md file was created as a planning document when that feature was worked on and may not be currently still in date, but may be useful for contributors to understand the architecture and design decisions.
- Development Tools - Test scripts and debugging utilities
We welcome contributions to the open-source core (packages/core/)!
What you can contribute:
- β New drawing tools and brushes
- β Animation features and effects
- β Export formats and converters
- β UI/UX improvements
- β Bug fixes and performance optimizations
- β Documentation and examples
What is proprietary:
- β Authentication system (
packages/premium/) - β Cloud storage features
- β Payment integration
Important: This project uses a monorepo structure with a private Git submodule for premium features.
Ascii-Motion/ # Main repository (public)
βββ packages/
β βββ core/ # Open source (MIT) - You work here!
β β βββ src/
β β β βββ components/
β β β βββ stores/
β β β βββ hooks/
β β β βββ utils/
β β βββ package.json
β βββ premium/ # Private submodule (Proprietary)
β βββ (not accessible to contributors)
βββ src/ # Legacy code (being migrated to core)
βββ package.json # Root workspace config
-
Clone the repository:
git clone https://github.com/cameronfoxly/Ascii-Motion.git cd Ascii-Motion npm install -
The
packages/premium/folder will be empty - This is expected! You don't need it to contribute. The app runs without premium features. -
Development:
npm run dev # Start dev server npm run test:run # Run tests (343 tests) npm run lint # Check code quality npm run build # Production build
-
All source code lives in
src/β not inpackages/core/(which is a shared UI component library). Your contributions go directly insrc/. -
Key files to know:
src/stores/timelineStore.tsβ Primary state (layers, keyframes, timeline)src/hooks/useKeyboardShortcuts.tsβ All keyboard shortcuts and undo/redosrc/components/features/ToolPalette.tsxβ Tool UI and optionssrc/utils/exportRenderer.tsβ All export format renderingsrc/types/timeline.tsβ Core type definitions
When writing code in src/, use these import patterns:
// Stores
import { useTimelineStore } from '../stores/timelineStore';
import { useCanvasStore } from '../stores/canvasStore';
import { useToolStore } from '../stores/toolStore';
// Utils
import { screenToLocal } from '../utils/layerTransformUtils';
import { compositeLayersAtFrame } from '../utils/layerCompositing';
// Types
import type { Layer, ContentFrame, KeyframeId } from '../types/timeline';
// UI Components
import { Button } from '../components/ui/button';- The main app (
src/folder) imports from bothcoreandpremium - When you run
npm run devfrom the root, both packages are built - If
packages/premium/is missing, the app will still work but without auth/cloud features - Your contributions to
coreare completely independent of premium features
# Run the full test suite (343 tests)
npm run test:run
# Run tests in watch mode during development
npm test
# Lint check
npm run lint
# TypeScript type check
npx tsc --noEmit
# Production build verification
npm run build- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-tool - Make your changes in
packages/core/ - Commit with clear messages:
git commit -m "Add gradient brush tool" - Push to your fork:
git push origin feature/amazing-tool - Open a Pull Request to the
mainbranch
PR Checklist:
- Changes don't modify premium code (
packages/premium/) - Code follows existing patterns and TypeScript strict mode
- Tests pass (
npm run test:run) - No linting errors (
npm run lint) - Build succeeds (
npm run build) - New features include tests where applicable
- PR description explains what and why
See CONTRIBUTING.md for detailed guidelines.
Dual License:
-
Core Features (
packages/core/) - MIT License- Free to use, modify, and distribute
- No restrictions on commercial use
-
Premium Features (
packages/premium/) - Proprietary License- Authentication and cloud storage
- Unauthorized copying or distribution prohibited
See individual LICENSE files for full details.
Made with β€οΈ for the ASCII art community