Skip to content

ihardk/syntaxify

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

63 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Syntaxify โšก

AST-based Flutter UI Code Generator with Multi-Style Design System

Stop writing repetitive UI code. Define components once, render in any design system.

pub package GitHub stars License: MIT Buy Me A Coffee


โšก Quick Win: Generate Screens in Seconds

// Create meta/login.screen.dart
final loginScreen = ScreenDefinition(
  id: 'login',
  appBar: AstNode.appBar(title: 'Login'),
  layout: AstNode.column(children: [
    AstNode.text(text: 'Welcome', variant: TextVariant.headlineLarge),
    AstNode.textField(label: 'Email', keyboardType: KeyboardType.email),
    AstNode.textField(label: 'Password', obscureText: true),
    AstNode.button(label: 'Login', onPressed: 'handleLogin'),
  ]),
);

Run: dart run syntaxify build Get: Complete Flutter screen in lib/screens/login_screen.dart

No boilerplate. No repetition. Just results. โœจ


๐Ÿ‘€ See It In Action

Syntaxify Demo

Check out the example app - A working Flutter app demonstrating all features with live style switching!

cd example && flutter run

๐Ÿค” Why Syntaxify?

The Problem: Flutter's Design System Scalability Crisis

Flutter developers face a fundamental dilemma when building production apps:

The Multi-Platform UI Duplication Problem:

  • Material Design for Android
  • Cupertino for iOS
  • Custom designs for brand identity

Traditional approach means writing everything 3 times:

// You write this for EVERY component!
Widget buildButton() {
  if (Platform.isIOS) {
    return CupertinoButton(
      onPressed: onPressed,
      child: Text(label),
    );
  } else if (useCustom) {
    return CustomButton(
      onPressed: onPressed,
      label: label,
    );
  } else {
    return ElevatedButton(
      onPressed: onPressed,
      child: Text(label),
    );
  }
}

Real-World Impact:

  • ๐Ÿข Large Apps: 100+ screens, 1000+ components
  • ๐Ÿ‘ฅ Team Scale: Multiple developers, changing requirements
  • ๐Ÿ”„ Maintenance Nightmare: "Change all buttons to rounded corners" = touching 500+ files
  • ๐Ÿ’ธ Cost: "Switch from Material to Cupertino" = rewriting the entire app
  • ๐ŸŽจ Design Changes: "Our designer wants a custom look" = building everything from scratch

The Solution: Separation of WHAT and HOW

Syntaxify delivers on Flutter's original promise: "write once, run anywhere" - but for design systems.

With Syntaxify:

// Write once
AppButton(label: 'Click Me', onPressed: ...)

// Renders appropriately everywhere
AppTheme(style: MaterialStyle())   // Material on Android
AppTheme(style: CupertinoStyle())  // iOS-native on iPhone
AppTheme(style: NeoStyle())        // Custom brand design

Change your entire app's design system in one line:

// Before: Material Design
AppTheme(style: MaterialStyle(), child: MyApp())

// After: iOS-native Cupertino
AppTheme(style: CupertinoStyle(), child: MyApp())
// Zero component code changes needed!

What Makes Syntaxify Different

Most Flutter solutions offer partial fixes:

  • โŒ Widget libraries - Still manual integration, not design-system-aware
  • โŒ Themes - Only styling, not structure
  • โŒ Code generation - Not multi-platform aware

Syntaxify combines all three:

  • โœ… Code generation - Eliminate boilerplate
  • โœ… Design system architecture - WHAT vs HOW separation
  • โœ… Multi-platform rendering - One component, any design
  • โœ… Type-safe APIs - Compile-time safety

๐ŸŽจ The Design System Architecture

The Renderer Pattern

Syntaxify uses a unique renderer pattern that separates concerns:

WHAT (Component Definition):

AppButton.primary(
  label: 'Click Me',
  onPressed: () => print('Hello!'),
)

HOW (Style Rendering):

  • Material: Renders as ElevatedButton with Material Design tokens
  • Cupertino: Renders as CupertinoButton with iOS styling
  • Neo: Renders with modern, neumorphic design

The Magic: Same component code, different visual output based on AppTheme:

AppTheme(
  style: MaterialStyle(),  // or CupertinoStyle() or NeoStyle()
  child: MaterialApp(home: YourApp()),
)

Why This Matters

  1. Write Once, Render Anywhere - One component definition works across all design systems
  2. Easy Theme Switching - Change one line to switch your entire app's design
  3. Consistent Behavior - Button logic stays the same, only visuals change
  4. Custom Styles - Create your own design system by implementing DesignStyle

๐Ÿ“ฆ What's Currently Available

๐ŸŒŸ Screen Generation from .screen.dart Files (Star Feature!)

The fastest way to build Flutter screens:

// meta/login.screen.dart
final loginScreen = ScreenDefinition(
  id: 'login',
  layout: AstNode.column(children: [
    AstNode.text(text: 'Welcome Back'),
    AstNode.textField(label: 'Email'),
    AstNode.button(label: 'Sign In', onPressed: 'handleLogin'),
  ]),
);

Run syntaxify build โ†’ Get a complete Flutter screen!

  • โœ… Generate entire screens from simple definitions
  • โœ… Editable after generation (you own the code)
  • โœ… Type-safe callbacks and imports
  • โœ… Proper structure and scaffolding
  • โœ… No boilerplate, no repetition

โœ… Components with Full Renderer Pattern

These components work with Material, Cupertino, and Neo styles:

  • AppButton - Buttons with variants (primary, secondary, outlined)
  • AppText - Text with typography variants (display, headline, title, body, label)
  • AppInput - Text fields with validation and keyboard types

๐Ÿšง Custom Components (Basic Support)

You can define custom components (e.g., Card, Badge, Avatar), and Syntaxify will:

  • โœ… Generate the component class
  • โœ… Create constructor and fields
  • โš ๏ธ Generate basic Container widget (not full renderer pattern yet)

Coming Soon: Full renderer pattern for more components (Card, Badge, Avatar, Chip, etc.)


๐Ÿš€ Complete Getting Started Guide

Step 1: Install Syntaxify

Option A: From pub.dev (Recommended)

# pubspec.yaml
dev_dependencies:
  syntaxify: ^0.1.0-alpha.1

Then run:

dart pub get

Option B: From GitHub (Latest)

# pubspec.yaml
dev_dependencies:
  syntaxify:
    git:
      url: https://github.com/ihardk/syntaxify.git
      ref: v0.1.0
      path: generator

โš ๏ธ Alpha Release: This package is in alpha. API may change. See CHANGELOG for updates.

Optional: Global Installation

If you want syntaxify available system-wide (not just in your project):

dart pub global activate syntaxify

Then you can run syntaxify commands from anywhere. Otherwise, use dart run syntaxify in your project.

Step 2: Initialize Your Project

cd your_flutter_project
dart run syntaxify init

This creates:

  • meta/ - Where you define component APIs
  • lib/syntaxify/design_system/ - Customizable design system

Step 3: Define Components

Edit meta/button.meta.dart:

import 'package:syntaxify/syntaxify.dart';

@SyntaxComponent(description: 'A customizable button')
class ButtonMeta {
  /// The button label text
  @Required()
  final String label;

  /// The action to trigger (e.g. 'action:login')
  @Optional()
  final String? onPressed;

  /// Button variant (filled, outlined, etc)
  @Optional()
  final String? variant;

  /// Button size (sm, md, lg)
  @Optional()
  final String? size;

  /// Whether the button shows loading state
  @Optional()
  @Default('false')
  final bool isLoading;

  /// Whether the button is disabled
  @Optional()
  @Default('false')
  final bool isDisabled;
}

Step 4: Build

dart run syntaxify build

This generates:

  • lib/syntaxify/generated/components/app_button.dart - The component
  • lib/syntaxify/design_system/ - Design system files (Material, Cupertino, Neo)
  • lib/syntaxify/index.dart - Barrel export

Step 5: Use in Your App

import 'package:flutter/material.dart';
import 'package:your_app/syntaxify/index.dart';

void main() {
  runApp(
    AppTheme(
      style: MaterialStyle(),  // Try CupertinoStyle() or NeoStyle()!
      child: MaterialApp(
        home: Scaffold(
          body: Center(
            child: AppButton.primary(
              label: 'Click Me',
              onPressed: () => print('Hello from Syntaxify!'),
            ),
          ),
        ),
      ),
    ),
  );
}

Step 6: Generate Screens (Optional)

Create meta/login.screen.dart:

import 'package:syntaxify/syntaxify.dart';

final loginScreen = ScreenDefinition(
  id: 'login',
  layout: AstNode.column(children: [
    AstNode.text(text: 'Welcome Back'),
    AstNode.textField(label: 'Email', keyboardType: KeyboardType.emailAddress),
    AstNode.textField(label: 'Password', obscureText: true),
    AstNode.button(label: 'Sign In', onPressed: 'handleLogin'),
  ]),
);

Run dart run syntaxify build again - generates lib/screens/login_screen.dart (editable!)


๐ŸŽฏ Real-World Example

Before Syntaxify (Manual Approach)

Material Button:

ElevatedButton(
  onPressed: onPressed,
  style: ElevatedButton.styleFrom(
    backgroundColor: Colors.blue,
    padding: EdgeInsets.all(16),
  ),
  child: Text(label),
)

Cupertino Button:

CupertinoButton.filled(
  onPressed: onPressed,
  padding: EdgeInsets.all(16),
  child: Text(label),
)

Custom Button:

Container(
  decoration: BoxDecoration(
    gradient: LinearGradient(...),
    borderRadius: BorderRadius.circular(12),
    boxShadow: [BoxShadow(...)],
  ),
  child: Material(
    color: Colors.transparent,
    child: InkWell(
      onTap: onPressed,
      child: Padding(
        padding: EdgeInsets.all(16),
        child: Text(label),
      ),
    ),
  ),
)

Problem: 3 different implementations, hard to maintain, inconsistent behavior.

After Syntaxify

One Definition:

AppButton.primary(label: 'Submit', onPressed: handleSubmit)

Three Renderings:

  • Wrap with MaterialStyle() โ†’ Material Design
  • Wrap with CupertinoStyle() โ†’ iOS Design
  • Wrap with NeoStyle() โ†’ Modern Design

Result: Consistent API, different visuals, easy to switch.


๐Ÿ“‚ Project Structure

your_project/
โ”œโ”€โ”€ meta/                          # YOU EDIT: Component & screen definitions
โ”‚   โ”œโ”€โ”€ button.meta.dart
โ”‚   โ”œโ”€โ”€ input.meta.dart
โ”‚   โ”œโ”€โ”€ text.meta.dart
โ”‚   โ”œโ”€โ”€ login.screen.dart
โ”‚   โ””โ”€โ”€ app_icons.dart
โ”‚
โ””โ”€โ”€ lib/
    โ”œโ”€โ”€ screens/                   # EDITABLE: Generated screens
    โ”‚   โ””โ”€โ”€ login_screen.dart      # Generated once, then you own it
    โ”‚
    โ””โ”€โ”€ syntaxify/
        โ”œโ”€โ”€ design_system/         # CUSTOMIZABLE: Styles & tokens
        โ”‚   โ”œโ”€โ”€ design_system.dart
        โ”‚   โ”œโ”€โ”€ app_theme.dart
        โ”‚   โ”œโ”€โ”€ styles/
        โ”‚   โ”‚   โ”œโ”€โ”€ material_style.dart
        โ”‚   โ”‚   โ”œโ”€โ”€ cupertino_style.dart
        โ”‚   โ”‚   โ””โ”€โ”€ neo_style.dart
        โ”‚   โ””โ”€โ”€ tokens/
        โ”‚       โ”œโ”€โ”€ button_tokens.dart
        โ”‚       โ””โ”€โ”€ input_tokens.dart
        โ”‚
        โ”œโ”€โ”€ generated/             # DON'T EDIT: Auto-regenerated
        โ”‚   โ””โ”€โ”€ components/
        โ”‚       โ”œโ”€โ”€ app_button.dart
        โ”‚       โ”œโ”€โ”€ app_input.dart
        โ”‚       โ””โ”€โ”€ app_text.dart
        โ”‚
        โ””โ”€โ”€ index.dart             # Barrel export

๐Ÿ“– API Reference

For detailed API documentation, see API Reference.

Quick Overview:

Component Description
AppButton Primary, secondary, outlined button variants
AppText Typography with 6 text style variants
AppInput Text fields with keyboard types & validation

Design Styles: MaterialStyle(), CupertinoStyle(), NeoStyle()

Import: import 'package:your_app/syntaxify/index.dart';


๐Ÿ”„ Development Workflow

  1. Define - Edit meta/*.meta.dart to define component APIs
  2. Build - Run dart run syntaxify build to generate implementations
  3. Use - Import from package:your_app/syntaxify/ and use
  4. Customize - Edit design system tokens in lib/syntaxify/design_system/
  5. Switch Styles - Change AppTheme(style: ...) to try different designs

Understanding Generated Code

Important: Two types of generated code with different lifecycles:

Components (Regenerate Every Build)

Location: lib/syntaxify/generated/components/ Behavior: Regenerated on EVERY syntaxify build Rule: โš ๏ธ DO NOT EDIT - Your changes will be lost!

// lib/syntaxify/generated/components/app_button.dart
// This file is REGENERATED on every build
class AppButton extends StatelessWidget {
  // Generated code - DO NOT MODIFY
}

Screens (Generate Once)

Location: lib/screens/ Behavior: Generated ONCE, then YOU own it Rule: โœ… FREELY EDIT - Won't be overwritten

// lib/screens/login_screen.dart
// Generated once, then it's yours to edit
class LoginScreen extends StatelessWidget {
  // Edit this freely - it won't be regenerated
}

What happens when you rebuild?

  • Components: Completely regenerated from meta files
  • Screens: Skipped (only generated if file doesn't exist)

๐Ÿ› ๏ธ Advanced Usage

For advanced topics, see the detailed documentation:


๐Ÿ› Troubleshooting

Having issues? See Troubleshooting Guide for common errors and solutions.

Quick fixes:

  • TextVariant.headline โ†’ Use TextVariant.headlineMedium
  • KeyboardType.email โ†’ Use TextInputType.emailAddress
  • Component not updating? โ†’ Edit meta/*.meta.dart, not generated files

Need help? GitHub Issues


โœจ Features

  • AST-Based Generation - Type-safe, declarative UI definitions
  • Renderer Pattern - Separates WHAT (behavior) from HOW (rendering)
  • Multi-Style Support - Material, Cupertino, Neo (3 components currently, more coming)
  • Smart Defaults - Auto-detects project structure
  • Screen Generation - Generate editable screen scaffolds
  • Design Tokens - Centralized styling with tokens
  • Git-Friendly - Clean, readable generated code
  • Extensible - Create custom design styles by implementing DesignStyle

๐Ÿ—บ๏ธ Roadmap

v0.1.0 (Current)

  • โœ… Core architecture with renderer pattern
  • โœ… 3 components (Button, Text, Input)
  • โœ… 3 design styles (Material, Cupertino, Neo)
  • โœ… Screen generation
  • โœ… Smart build defaults

v0.2.0 (Next)

  • ๐Ÿ”„ More components with full renderer pattern:
    • Card, Badge, Avatar, Chip, Switch, Checkbox, Radio
  • ๐Ÿ”„ Golden tests for visual regression
  • ๐Ÿ”„ Better error messages

v1.0.0 (Future)

  • ๐Ÿ”ฎ Complete component library
  • ๐Ÿ”ฎ Theme editor UI
  • ๐Ÿ”ฎ VS Code extension
  • ๐Ÿ”ฎ Component marketplace

๐Ÿ“š Documentation

Guide Description
Getting Started Installation & first steps
API Reference Component usage & options
Design System Renderer pattern & custom styles
Troubleshooting Common issues & solutions
User Manual Comprehensive user guide
Developer Manual Architecture & contributing

๐Ÿค Contributing

See Developer Manual for architecture details and contribution guidelines.

๐Ÿ“„ License

MIT License - See LICENSE for details


Built with โค๏ธ for Flutter developers who value consistency, productivity, and beautiful code

โญ Star us on GitHub โ€ข ๐Ÿ“ฆ pub.dev โ€ข โ˜• Buy Me a Coffee

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published