Back to Articles

blobs.app: How a Browser-Based SVG Generator Bridges Web and Flutter Development

[ View on GitHub ]

blobs.app: How a Browser-Based SVG Generator Bridges Web and Flutter Development

Hook

Most design tools export SVG. Only one exports production-ready Flutter code from the same blob shape—and it runs entirely offline in your browser.

Context

Organic blob shapes became a design trend around 2018, appearing everywhere from landing pages to mobile app backgrounds. Designers initially created these in Figma or Illustrator, manually tweaking Bézier curves until shapes felt ‘organic enough.’ Developers received static SVG exports, then faced the tedious task of converting them to platform-specific code—particularly painful for Flutter developers who needed CustomPainter implementations or complex Path objects.

The first wave of blob generators solved half the problem: tools like blobmaker.app automated shape creation, eliminating manual curve manipulation. But the developer handoff remained broken. A designer would generate a blob, export SVG, and a Flutter developer would spend 20 minutes translating it into Dart code, calculating control points and adjusting coordinates. blobs.app emerged to close this gap, recognizing that the blob-to-code pipeline needed automation for both web and mobile ecosystems.

Technical Insight

Browser Only

complexity, randomness

point calculations

visual output

serialized data

SVG markup

Dart classes

config params

shareable link

User Input

Sliders & Controls

Blob Generator

Algorithm

SVG Path Builder

Bézier Curves

Canvas Preview

Real-time Render

Code Exporters

SVG Code

Flutter Code

URL State Manager

System architecture — auto-generated

At its core, blobs.app uses a parametric approach to generate organic shapes based on radial point distribution with controlled randomness. The application calculates points around a circle, applies random offsets within configurable bounds, then connects them using SVG path commands with cubic Bézier curves for smoothness.

The architecture is surprisingly simple yet powerful: pure client-side JavaScript with no backend dependency. All shape generation, styling, and code export happens in the browser’s JavaScript runtime. The app stores configuration state in URL parameters, enabling shareable links without database persistence. When you adjust complexity or randomness sliders, the app regenerates the blob by recalculating point positions and curve control points, updating both the visual preview and export code in real-time.

Here’s what a typical exported SVG structure looks like:

<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
  <path fill="#FF6B9D" d="M43.3,-62.1C55.1,-54.2,63.5,-41.5,68.2,-27.4C72.9,-13.3,73.9,2.1,69.8,15.7C65.7,29.3,56.5,41.1,44.6,49.2C32.7,57.3,18.1,61.7,2.8,57.8C-12.5,53.9,-28.4,41.7,-40.8,28.3C-53.2,14.9,-62.1,0.3,-63.4,-15.7C-64.7,-31.7,-58.4,-49.1,-46.8,-57.3C-35.2,-65.5,-18.6,-64.5,-1.8,-62.1C15,-59.7,31.5,-70,43.3,-62.1Z" />
</svg>

But the real engineering achievement is the Flutter code generation. The app doesn’t just dump coordinates—it generates idiomatic Dart code using Flutter’s CustomPaint widget:

class BlobPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Color(0xFFFF6B9D)
      ..style = PaintingStyle.fill;
    
    final path = Path();
    path.moveTo(size.width * 0.216, size.height * 0.189);
    path.cubicTo(
      size.width * 0.276, size.height * 0.229,
      size.width * 0.318, size.height * 0.293,
      size.width * 0.341, size.height * 0.363
    );
    // ... additional curve commands
    path.close();
    
    canvas.drawPath(path, paint);
  }
  
  @override
  bool shouldRepaint(CustomPainter oldDelegate) => false;
}

This code is immediately usable in Flutter projects—just copy, paste, and render with CustomPaint(painter: BlobPainter()). The coordinate normalization (multiplying by size.width and size.height) ensures the blob scales correctly across different device sizes, a detail many manual conversions miss.

The styling system deserves attention too. Beyond basic fills, blobs.app supports gradients, patterns, and image clipping. When you select image clipping, the app uses SVG’s <clipPath> element to mask an image with the blob shape—a technique that requires understanding both SVG coordinate systems and the interaction between <defs>, <clipPath>, and <image> elements. The generated code handles viewBox scaling automatically, preventing the common pitfall where clipped images appear stretched or misaligned.

The PWA implementation enables offline functionality through service workers that cache the application shell and assets. This architectural choice makes sense for a tool developers use intermittently—you don’t want a network dependency when you need a quick blob shape during a design sprint. The service worker caching strategy appears to use a cache-first approach for static assets, ensuring instant load times on repeat visits.

URL-based state management works through query parameters encoding shape configuration: complexity, randomness, color values, and gradient stops all serialize to the URL. This enables collaborative workflows—a designer can generate a blob, copy the URL, and send it to a developer who sees the exact same shape with identical parameters. It’s a clever solution that avoids authentication, databases, and GDPR concerns while enabling state persistence and sharing.

Gotcha

The Flutter code export, while impressive, has practical limitations. The generated CustomPainter is static—it doesn’t support animation or dynamic reshaping without significant manual refactoring. If you need blob shapes that morph or animate, you’ll need to implement interpolation logic between multiple paths yourself, which involves complex math around matching point counts and curve alignment.

The tool also lacks programmatic access. There’s no API, CLI, or npm package for automated blob generation. If you’re building a design system that needs 50 blob variations with consistent parameters, you’re stuck manually generating and exporting each one. The browser-only interface becomes a bottleneck for batch operations or CI/CD integration. You can’t script blob generation as part of a build process or generate variations programmatically based on brand color schemes.

Image clipping works well for simple use cases but breaks down with complex images or performance-sensitive contexts. SVG clip paths can cause rendering performance issues on older devices, especially when combined with filters or multiple layered blobs. The exported Flutter code doesn’t include optimizations like rasterization caching, which you’d need to add manually for smooth 60fps performance in scrolling lists or animations.

Verdict

Use if: You need quick, production-ready organic shapes for web projects or Flutter apps with immediate visual feedback and zero setup. It’s particularly valuable when you want sharable URLs for design collaboration, need Flutter code without manual SVG-to-Dart translation, or want to iterate on blob aesthetics with real-time styling previews. The offline PWA capability makes it reliable for air-gapped environments or unstable connections. Skip if: You need animated or morphing blobs (you’ll want a JavaScript animation library like Flubber or custom interpolation code), require programmatic generation for design systems at scale (consider writing a custom generator with libraries like d3-shape), or need precise geometric control beyond organic randomness (stick with vector design tools like Figma or Illustrator). Also skip if you’re building performance-critical mobile UIs with dozens of blobs—the generated Flutter code needs optimization work for those scenarios.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/developer-tools/lokesh-coder-blobs-app.svg)](https://starlog.is/api/badge-click/developer-tools/lokesh-coder-blobs-app)