mikewhob

Blog

Building a Flutter JSON Editor: From Concept to Package

· 4 min read · Michael Whobrey
FlutterDartJSONJSON EditorSpectre JsonOpen SourceCross-Platform DevelopmentUI ComponentsDeveloper Toolspub.dev

The Problem

While working on various Flutter applications, I repeatedly needed a way to display and edit JSON data. The existing solutions were either too basic, not customizable enough, or didn’t provide the user experience I was looking for.

I wanted something that would:

  • Provide syntax highlighting for better readability
  • Offer both tree view and raw text editing modes
  • Include real-time validation with helpful error messages
  • Be highly customizable to match different app themes
  • Work seamlessly across all Flutter platforms

Design Decisions

The first major decision was choosing between a single-mode editor or a multi-mode approach. After prototyping both, I settled on a flexible system that supports three view types:

1. Dual View Mode

Shows both a tree view and a raw text editor with tabs, allowing users to switch between visual and text-based editing. This proved to be the most popular choice during user testing.

2. Tree-Only Mode

Perfect for applications where you want to prevent users from making syntax errors. The tree view provides a safe, guided editing experience.

3. Raw-Only Mode

For power users who prefer direct text editing with syntax highlighting and validation.


Technical Implementation

The core of the widget is built around Flutter’s CustomScrollView and custom painting for the tree visualization. Here’s a simplified version of the main widget structure:

class JsonEditor extends StatefulWidget {
  final Map initialData;
  final Function(Map) onDataChanged;
  final ViewType viewType;
  final JsonEditorTheme theme;
  final bool allowCopy;
  final String? title;

  const JsonEditor({
    Key? key,
    required this.initialData,
    required this.onDataChanged,
    this.viewType = ViewType.dual,
    this.theme = const RedPandaTheme(),
    this.allowCopy = true,
    this.title,
  }) : super(key: key);

  @override
  _JsonEditorState createState() => _JsonEditorState();
}

Editor Modes & Data Flow

To help visualize how the widget works, here’s a Mermaid diagram showing the three editor modes and the data flow including validation and errors:

flowchart TD
  A[JSON Editor Widget] --> B{View Mode?}
  B --> |Dual View| C[Tree View]
  B --> |Dual View| D[Raw Text Editor]
  B --> |Tree-Only| C
  B --> |Raw-Only| D

  C --> E[User Edits JSON in Tree]
  D --> F[User Edits JSON in Text]

  E --> G[Validation & Syntax Check]
  F --> G[Validation & Syntax Check]

  G --> |Valid| H[onDataChanged Callback]
  G --> |Error| I[Show Error Message]

  H --> J[App Receives Updated JSON]

  style E fill:#d4f1f9,stroke:#333,stroke-width:1px
  style F fill:#d4f1f9,stroke:#333,stroke-width:1px
  style G fill:#fff3bf,stroke:#333,stroke-width:1px
  style H fill:#c3f7d4,stroke:#333,stroke-width:1px
  style I fill:#f8d7da,stroke:#333,stroke-width:1px

Challenges and Solutions

Performance with Large JSON Files

Handling large JSON files without UI freezes was a major challenge. Solution: Implemented virtual scrolling and lazy loading for the tree view, only rendering visible nodes.

Cross-Platform Consistency

Ensuring consistent behavior across Android, iOS, Web, Windows, macOS, and Linux required careful testing and platform-specific tweaks.

Theme Customization

Theming needed to be flexible to work with any app design. I implemented a theme system that allows full customization of colors, fonts, and spacing.


Testing Strategy

Comprehensive testing was essential for a production-ready widget:

  • Unit tests: JSON parsing and validation logic
  • Widget tests: UI behavior and user interactions
  • Integration tests: Complete editing workflow
  • Performance tests: Large JSON files
  • Platform-specific tests: All supported platforms

Publishing and Distribution

Publishing to pub.dev required careful attention to documentation, examples, and version management. The package includes:

  • Comprehensive API documentation
  • Multiple usage examples
  • Performance benchmarks
  • Migration guides for breaking changes

Lessons Learned

This project taught me several valuable lessons about Flutter development and package creation:

“The key to a successful Flutter package is not just functionality, but also developer experience. Every API decision should be made with the end developer in mind.”

Key Takeaways

  • Focus on usability: Tree and raw views cater to different user skill levels
  • Optimize performance for large datasets using lazy rendering
  • Ensure cross-platform consistency for a seamless experience
  • Provide comprehensive documentation and examples for developers

Future Plans

The journey doesn’t end with the initial release. Planned improvements include:

  • Adding JSON Schema validation
  • Implementing collaborative editing features
  • Supporting more export formats (YAML, XML)
  • Creating a web-based demo application

Conclusion

Building Spectre Json was challenging but incredibly rewarding. It pushed me to learn custom painting, performance optimization, and cross-platform Flutter development.

The positive feedback from the community has been amazing, and I’m excited to continue improving the package based on user needs.

If you’re interested in trying out Spectre Json, you can find it on pub.dev.

Enjoyed this? Share it, or reply by email — comments are retired here to keep the site fast and low-maintenance.