A community-driven Flutter app aiming to provide professional-grade drawing and painting tools that rival paid commercial software - completely free and open source.
Built with Flutter for cross-platform excellence, fPaint empowers artists, designers, and creators with powerful raster graphics tools across iOS, Android, macOS, Windows, Linux, and Web from a single codebase.
To create a free alternative to expensive commercial graphics software through community collaboration. We believe great tools should be accessible to everyone, and Flutter's cross-platform capabilities make this vision possible.
- Professional Drawing Tools - Advanced brushes, pressure sensitivity, and precision controls
- Brushes & Effects - A unified tool model: everything is a brush, selection is a mask — even effects arm as brushes. See BRUSHES_AND_EFFECTS.md
- Layer Management - Full layer system with blending modes, opacity, and organization
- Selection Tools - Magic Wand, lasso, rectangle, and advanced selection capabilities
- Color Management - Professional color picker with palettes, gradients, and color harmony
- File Format Support - PNG, JPEG, TIFF, WEBP, HEIC, OpenRaster (ORA), Photoshop (PSD, import), and more
- Cross-Platform - Consistent experience across all major platforms
- Undo/Redo - Robust history system for creative freedom
- Responsive UI - Optimized for touch, mouse, and stylus input
This is more than an app - it's a movement. We're building the future of free graphics software together. Whether you're a:
- Flutter Developer - Help us push the boundaries of what's possible with Flutter
- Graphics Programmer - Implement advanced algorithms and optimizations
- UI/UX Designer - Create intuitive interfaces that inspire creativity
- Artist/Designer - Provide feedback on tools and workflows
- Tester - Help ensure quality across all platforms
- Documentation Writer - Make our project accessible to newcomers
Your contribution matters. Every line of code, every bug report, every feature suggestion brings us closer to replacing paid commercial software with a truly free alternative.
Unlike commercial alternatives, fPaint will always remain completely free with:
- 🙅🏼 No ads or monetization
- 🙅🏼 No feature restrictions
- 🙅🏼 No premium tiers
- ✅ Full source code transparency
- ✅ Community-driven development
- ✅ Cross-platform availability
We're building toward feature parity with commercial graphics editors. Current priorities include:
- Multi-layer system with blending modes
- Advanced selection tools (Magic Wand, Lasso)
- Professional color management
- Multiple file format support
- Advanced brush engines (contributions needed!)
- Text tool improvements (contributions needed!)
- Performance optimizations (contributions needed!)
- Non-destructive filters and effects
- Advanced typography and text-on-path
- CMYK color management
- Scripting/automation
Your expertise in any of these areas would accelerate our progress tremendously!
- Flutter SDK (3.35.7 or higher)
- Dart SDK (3.9.2 or higher)
- Edit and build on macOS, Windows, or Linux
- IDE: VS Code or Android Studio
- iOS Simulator / Android Emulator (for mobile development)
-
Clone the repository
git clone https://github.com/vteam-com/fPaint.git
-
Navigate to the project directory
cd fPaint -
Install dependencies
flutter pub get
-
Run the app
flutter run
flutter build linux produces a portable bundle, and the same bundle is what the website offers for download. The first time that bundle's executable runs, it publishes the desktop entry and the icon it carries — share/applications/com.vteam.fpaint.desktop and share/icons/hicolor/512x512/apps/com.vteam.fpaint.png — into the user's data directory ($XDG_DATA_HOME, usually ~/.local/share), with Exec aimed at the directory the application runs from. That is what lets a desktop environment draw fPaint's icon and name in the task bar, the window switcher and the window frame, and start the bundle from the application menu; on Wayland it is the only way, since an application cannot set its own window icon there. The entry is refreshed whenever the bundle moves, a desktop entry installed system-wide is left in charge, and FPAINT_SKIP_DESKTOP_INTEGRATION=1 turns the publishing off for packagers that ship their own entry.
fPaint includes comprehensive integration tests that demonstrate advanced painting features and multi-layer scene creation. The integration tests use human-like gestures to simulate real user interactions and create complete artwork scenes.
To run the integration tests:
# Run all unit test
flutter test
# Run integration test
./tool/run_integration_test.shThe integration tests demonstrate:
- Multi-layer scene creation: Sky gradients, sun with radiating rays, land, houses, and fences
- Advanced drawing tools: Circles, rectangles, lines with human-like gesture simulation
- Gradient fills: Linear and radial gradients for backgrounds and effects
- Layer management: Creating, switching, and organizing artwork layers
- Selection tools: Circle selection for precise area targeting
- Color management: Dynamic color palette and fill operations
The integration_test/integration_helpers.dart file provides reusable helper functions for:
- Human-like drawing gestures (circles, rectangles, lines)
- Layer management operations
- Gradient fill operations
- Color picker interactions
- UI element tapping and navigation
- Launch the app
- Choose your preferred brush size and color
- Start drawing on the canvas
- Use the SidePanel to:
- Change colors
- Adjust brush size
- Use advanced selection tools such as Magic Wand selection
- Manage layers efficiently
- Undo/Redo actions
- Clear the canvas
- Save your artwork
We follow the DRY (Don't Repeat Yourself) principle—avoid code duplication by extracting reusable logic into functions, classes, or constants.
We also adhere to the SOLID principles:
- Single Responsibility: Each class/module should have one responsibility.
- Open/Closed: Code should be open for extension, closed for modification.
- Liskov Substitution: Subtypes must be substitutable for their base types.
- Interface Segregation: Prefer many small, specific interfaces over large, general ones.
- Dependency Inversion: Depend on abstractions, not concretions.
We welcome contributions! Please see our Contributing Guide for details on how to get started.
Every push to main triggers the following automated pipeline:
Push to main
└─► CI (ci.yml)
├─ Analyze (flutter analyze, dart format)
└─ Test (flutter test --coverage → Codecov)
│
▼ on success
Deploy Pipeline (firebase-hosting-merge.yml)
├─► Build Linux ─┐
├─► Build Windows ├─ parallel
├─► Build macOS ─┘
│ │
│ ▼ all complete
└─► Build Web + Deploy
├─ flutter build web
├─ Copy desktop zips into build/web/downloads/
└─ Deploy to paint.vteam.com (Firebase Hosting)
| Workflow | File | Trigger |
|---|---|---|
| CI | .github/workflows/ci.yml |
Push/PR to main or develop |
| Deploy | .github/workflows/firebase-hosting-merge.yml |
After CI succeeds on main |
| PR Preview | .github/workflows/firebase-hosting-pull-request.yml |
Pull requests |
| Desktop Only | .github/workflows/build-apps.yml |
Manual (workflow_dispatch) |
The desktop downloads at paint.vteam.com/downloads/ are built and deployed automatically with each release. The "Available on..." page in the app links directly to these URLs.
Please read our Code of Conduct before contributing.
If you discover a security vulnerability, please see our Security Policy.
This project is licensed under the MIT License - see the LICENSE file for details.
<?xml version="1.0" encoding="UTF-8"?>
<image xmlns:drawpile="http://paint.vteam.com/"
xmlns:mypaint="http://mypaint.org/ns/openraster" w="800" h="800" version="0.0.6" xres="72" yres="72" drawpile:framerate="24">
<stack>
<layer src="data/layer-0103.png" x="134" y="91" opacity="1.0000" name="birds"/>
<layer src="data/layer-0100.png" y="268" opacity="1.0000" name="Cloud"/>
<layer src="data/layer-0101.png" y="579" opacity="1.0000" name="Dirt"/>
<layer src="data/layer-0102.png" opacity="1.0000" name="sky"/>
<layer name="Background" src="data/background.png" mypaint:background-tile="data/background-tile.png"/>
</stack>
</image>These diagrams are generated by fCheck on every run of tool/check.sh.
To regenerate them on their own, run:
dart pub global activate fcheck
dart pub global run fcheck --svgPlease contribute and report issues on the GitHub repository. https://github.com/vteam-com/fPaint
