A powerful web-based tool for creating and customizing Material Design themes for Flutter applications. Built with React, TypeScript, and Tailwind CSS, this tool provides an intuitive interface for designing both light and dark themes with real-time preview capabilities.
- Dual Theme Editing: Create and edit both light and dark themes simultaneously
- Real-time Preview: See your theme changes instantly in a mobile device preview
- Token-based Editing: Use prebuilt color tokens for consistent theming
- JSON Editor: Direct JSON editing with syntax validation
- Import/Export: Import existing themes and export in multiple formats
- Material Design Tokens: Complete Material 3 color scheme support
- Custom Enum Tokens: Additional semantic tokens (warning, success, information, etc.)
- Surface Variants: Full surface container hierarchy support
- Accessibility: Automatic contrast ratio calculations
- JSON Format: Standard theme configuration files
- Dart Code: Ready-to-use Flutter theme classes
- Clipboard Copy: Quick sharing of theme configurations
- File Download: Direct download of theme files
- Node.js 18+
- npm or yarn
- Clone the repository:
git clone <repository-url>
cd material-theme-builder- Install dependencies:
npm install- Start the development server:
npm run dev- Open your browser and navigate to
http://localhost:3000
# Build client for static hosting (GitHub Pages)
npm run build:client
# Build full application with server
npm run build
npm startThe project includes GitHub Actions workflow for automatic deployment to GitHub Pages. See DEPLOYMENT.md for detailed instructions.
Quick Setup:
- Push your code to GitHub
- Enable GitHub Pages in repository settings
- Select "GitHub Actions" as the source
- The workflow will automatically deploy on every push to
main
Live Demo: https://[username].github.io/material-theme-builder/
- Start with Defaults: The app loads with Material Design default colors
- Choose Your Seed Color: Use the color picker to set your primary brand color
- Customize Tokens: Use the token editor to adjust individual color values
- Preview Changes: See your theme applied to various UI components in real-time
- Export Your Theme: Download as JSON or Dart code
- Click the "Import Theme" button in the theme editor
- Select a JSON theme file
- The theme will be loaded and displayed immediately in the preview
- Make adjustments as needed
- Visual color picker interface
- Organized by token categories (Primary, Secondary, Surface, etc.)
- Real-time updates as you adjust colors
- Direct JSON editing with syntax highlighting
- Validation and error checking
- Apply changes button to update the theme
The preview panel shows your theme applied to:
- App Bar: Primary color usage
- Cards: Surface and container colors
- Form Elements: Input fields, checkboxes, switches
- Navigation: Bottom navigation with active states
- Status Indicators: Warning, success, and information alerts
material-theme-builder/
├── client/ # React frontend
│ ├── src/
│ │ ├── components/
│ │ │ ├── theme-builder/ # Theme editing components
│ │ │ └── ui/ # Reusable UI components
│ │ ├── pages/ # Application pages
│ │ └── hooks/ # Custom React hooks
├── server/ # Express backend
├── shared/ # Shared TypeScript schemas
└── package.json
- Manages theme state and updates
- Handles light/dark theme switching
- Provides theme data to all components
- Main editing interface with tabs
- Token editor and JSON editor modes
- Import/export functionality
- Real-time theme preview
- Mobile device frame simulation
- Interactive UI component showcase
- Visual color picker interface
- Organized token categories
- Real-time color updates
- Theme State: Managed by React Context
- Color Updates: Flow from editor to context
- Preview Updates: Automatic re-rendering of preview components
- Export: Theme data converted to various formats
interface MaterialColorScheme {
// Primary colors
primary: string;
onPrimary: string;
primaryContainer: string;
onPrimaryContainer: string;
// Secondary colors
secondary: string;
onSecondary: string;
secondaryContainer: string;
onSecondaryContainer: string;
// Surface colors
surface: string;
onSurface: string;
surfaceVariant: string;
onSurfaceVariant: string;
// ... additional Material 3 tokens
}interface CustomEnumTheme {
// Semantic colors
warning: string;
onWarning: string;
warningContainer: string;
onWarningContainer: string;
success: string;
onSuccess: string;
successContainer: string;
onSuccessContainer: string;
information: string;
onInformation: string;
informationContainer: string;
onInformationContainer: string;
// ... additional custom tokens
}The project has been migrated from the original theme format to a new extended colors structure that matches Figma's Material Theme Builder plugin format. This migration includes:
- Extended Colors: All semantic and tag tokens moved from
schemes.light/darktoextendedColorsarray - Type Safety: Strict TypeScript types for all extended color names
- Runtime Accessors: Helper functions
getExtended()andgetExtendedHex()for accessing extended colors - Automatic Migration: Scripts to migrate theme files and update code references
# Run the main theme migration
npm run migrate:theme
# Verify migration results
npm run verify:migration
# Preview code changes (dry run)
npm run codemod:tags:dry
# Apply code changes
npm run codemod:tags- Input:
schemas/original.json(or fallback to/mnt/data/original.json) - Output:
target.generated.jsonwith migrated structure - Extended Colors: 48 total tokens (15 semantic + 33 tag tokens)
- Clean Schemes: All extended tokens removed from light/dark schemes
- Type Generation: Auto-generates
src/theme/extended-tags.generated.ts
interface ExtendedColor {
name: ExtendedTagName; // e.g., "warningText", "blueTagText"
color: string; // hex color "#RRGGBB"
description: string; // human readable description
fallback: string; // fallback description
harmonized: false; // always false per requirements
}import { getExtendedHex, getTagHex } from '@/theme';
// Before migration:
// const color = theme.schemes.light.warningText;
// After migration:
const color = getExtendedHex(theme, 'warningText');
// or with fallback:
const color = getTagHex(theme, 'warningText'); // returns "#000000" if not foundIf you need to rollback the migration:
- Restore the original
target.generated.jsonfrom backup - Run
npm run codemod:tagsto revert code changes - Restore the original
src/theme/extended-tags.generated.ts
- Frontend: React 18, TypeScript, Tailwind CSS
- Backend: Express.js, Node.js
- UI Components: Radix UI primitives
- State Management: React Context + Hooks
- Build Tool: Vite
- Package Manager: npm
@radix-ui/react-*: UI component primitiveslucide-react: Icon librarytailwindcss: Utility-first CSS frameworkzod: Schema validationframer-motion: Animation library
npm run dev # Start development server
npm run build # Build for production
npm run start # Start production server
npm run check # TypeScript type checking
npm run migrate:theme # Run theme migration script
npm run verify:migration # Verify migration results
npm run codemod:tags:dry # Preview codemod changes
npm run codemod:tags # Apply codemod changes
npm run test:theme # Run theme verification tests- Intuitive Interface: Clean, professional design for developers
- Real-time Feedback: Instant preview updates
- Flexible Editing: Multiple ways to customize themes
- Accessibility: WCAG compliant color contrast ratios
- Efficient Updates: Optimized re-rendering
- Fast Preview: Smooth theme switching
- Lightweight: Minimal bundle size
- Modular Architecture: Easy to add new token types
- Plugin System: Support for custom export formats
- API Ready: Backend prepared for future integrations
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow TypeScript best practices
- Use conventional commit messages
- Ensure all tests pass
- Update documentation as needed
This project is licensed under the MIT License - see the LICENSE file for details.
- Material Design: Google's design system that inspired this tool
- Flutter Team: For the excellent theming system
- Radix UI: For the accessible component primitives
- Tailwind CSS: For the utility-first styling approach
For questions, issues, or feature requests:
- Open an issue on GitHub
- Check the documentation
- Review existing discussions
Built with ❤️ for the Flutter community