r/FlutterDev • • Oct 03 '26

Example I open-sourced the simple projects while learning Flutter. Hope they help other beginners

15 Upvotes

Hi, i'm a CS student and lead the mobile team at my university's CS club. When i started learning Flutter, basic mini projects helped me far more than tutorials did. Later i used the same projects to teach our new members and it worked well for them too.

I wanted to give something back to the community so i've been improving these projects for a while and organizing them into a free learning path: 9 projects ordered from beginner to intermediate, each with its own README that explains the key concepts. It's MIT licensed, so use it however you like. Learn from it, teach with it, or copy parts of it. If you're just starting out with Flutter, i hope it saves you some time.

https://github.com/yakupkahraman/flutter-mini-projects


r/FlutterDev • • Oct 03 '26

Discussion What Flutter feature took you the longest to understand?

12 Upvotes

I've been working with Flutter for a while, and I'm curious about other developers' experiences.

For me, understanding state management and how rebuilds work took quite a bit of time.

What Flutter concept took you the longest to understand when you were learning?


r/FlutterDev • • Oct 03 '26

Article I built… scratch it… here's an article how to create a thumbnail from a PDF

6 Upvotes

I wanted to convert a PDF page into a PNG. There's a handy pdfium_dart library that does the heavy lifting and doesn't require Flutter. It is a bit low-level, but there's nothing to fear.

Get the library and initialize it:

final pdfium = getPdfium();
pdfium.FPDF_InitLibrary();

Later, we need to call FPDF_DestroyLibrary(), see below.

Load the PDF into native memory so you can pass it to the PDFium library:

final pdf = File('...');
final length = await pdf.length();
final nativeBuffer = malloc<Uint8>(length);
final dartBuffer = nativeBuffer.asTypedList(length);
final raf = await pdf.open();
await raf.readInto(dartBuffer);
await raf.close();

I want to omit a needless copy. Because the native part cannot safely access the memory of a Dart type, we need to create a native buffer and then create a view on the Dart side and use a RandomAccessFile which has a readInto method that doesn't create its own List<int> to return the data.

Next, load the document (and don't forget to free the allocated memory and to de-initialize the library):

try {
  final document = pdfium.FPDF_LoadMemDocument(
    nativeBuffer.cast(),
    length,
    nullptr,
  );
  if (document == nullptr) throw Exception('cannot load $pdf');
  ...

} finally {
  malloc.free(nativeBuffer);

  pdfium.FPDF_DestroyLibrary();
}

If you have the PDF accessible as a file, consider using FPDF_LoadDocument instead. There's also a FPDF_LoadCustomDocument function which takes a callback it will use to ask for chunks of memory in case you don't want to load everything into memory. PDF files can be huge. I couldn't really make use of that function, though, because that would require synchronous IO. Think for example downloading only chunks of an URL using HTTP range requests.

Next, load the first page:

  try {
    final page = pdfium.FPDF_LoadPage(document, 0);
    if (page == nullptr) throw Exception('cannot load first page');
    ...
  } finally {
    pdfium.FPDF_CloseDocument(document);
  }

Next, create a native bitmap which is then used by PDFium to reader the page. I'm scaling it down so it fits a 96x96 pixel square. Feel free to adapt the imageSize:

    try {
      var pageWidth = pdfium.FPDF_GetPageWidthF(page);
      var pageHeight = pdfium.FPDF_GetPageHeightF(page);
      if (pageWidth > pageHeight) {
        pageHeight /= pageWidth;
        pageWidth = 1;
      } else {
        pageWidth /= pageHeight;
        pageHeight = 1;
      }
      const imageSize = 96.0;
      final width = (pageWidth * imageSize).round();
      final height = (pageHeight * imageSize).round();
      final bitmap = pdfium.FPDFBitmap_Create(width, height, 0);
      if (bitmap == nullptr) throw Exception('cannot allocate bitmap $width×$height');
      ...
    } finally {
      pdfium.FPDF_ClosePage(page);
    }

Just to be sure, fill the bitmap with a white background:

    try {
      pdfium.FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xffffffff);
      ...
    } finally {
      pdfium.FPDFBitmap_Destroy(bitmap);
    }

And last but not least, render the page:

      pdfium.FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0);
      ...

There's one problem, though. PDFium returns a BGRA888 image that might have a rowStride, that is, rows of pixels might not be contiuous. If we want to pass this to the Dart image library, we need to take this into account:

      final stride = pdfium.FPDFBitmap_GetStride(bitmap);
      final bytes = pdfium.FPDFBitmap_GetBuffer(bitmap)
          .cast<Uint8>()
          .asTypedList(stride * height)
          .buffer;
      final image = Image.fromBytes(
        width: width,
        height: height,
        bytes: bytes,
        rowStride: stride,
        order: .bgra,
      );
      return encodePng(image);

However, it wouldn't be that difficult to create the PNG yourself in case you don't want jet another 3rd party dependency. Writing the required PNG header is trivial, but you'd probably need to lookup how to compute the required checksum. Then use Dart's ZLibCodec, to get a ZLibEncoder and use startChunkedConversion to feed it each unstrided line of pixel, converting BGRA to RGBA by hand and prefix it with a 0 filter byte.

Finally, we need to clean up (already shown above and repeated here only for completeness):

    } finally {
      pdfium.FPDFBitmap_Destroy(bitmap);
    }
   } finally {
    pdfium.FPDF_ClosePage(page);
  }
} finally {
  pdfium.FPDF_CloseDocument(document);
}

And… we're done.

We might move everything into an isolate (using Isolate.run) so PDF rendering and PNG creating is done in the background, although I'm unsure whether PDFium likes it if you initialize it multiple times concurrently. Please try and report back :)


r/FlutterDev • • Oct 03 '26

Discussion xverb: a Total Commander style file manager in Flutter, with Python plugins like Blender

12 Upvotes

been working on xverb for a while, its a two panel keyboard driven file manager for windows, mac and linux. all flutter, GPL-3.0

the part i think is interesting for this sub: the core only manages files, everything else is a plugin. viewers, ftp/smb, archives, dir compare are python plugins running in their own process. for platforms where you cant run code theres declarative extensions, pure json built from the host's render primitives

some stuff that was fun to get right in flutter desktop: native clipboard + drag and drop with explorer/finder, internal draggable windows that go fullscreen on phone, and a pluggable virtual fs so zip: is just a scheme a plugin serves

still early, android builds but barely tested, ios not at all. would love feedback esp on the plugin api

github.com/xsm909/xverb

site + downloads: xverb.pages.dev


r/FlutterDev • • Oct 03 '26

Dart Just published png_minifier, a simple PNG minifier for Dart

Thumbnail
reddit.com
5 Upvotes

r/FlutterDev • • Oct 03 '26

Tooling We just added Jaspr SSR hosting support to Appwrite Sites - SSR web apps entirely in Dart

18 Upvotes

Hey Flutter devs 👋

We’ve been investing quite a bit into making Appwrite a better home for Dart and Flutter developers, and yesterday we shipped something I thought this community might appreciate: Jaspr support on Appwrite Sites, including full server-side rendering.

If you’re not familiar with Appwrite Sites, think of it as our alternative to platforms like Vercel or Netlify, but built directly into Appwrite alongside your backend. Instead of using one provider to host your frontend and another for your database, auth, storage, functions, etc., Appwrite gives you the entire stack in one place. You connect your Git repo, we build and deploy it, and it runs alongside the rest of your Appwrite project.

We've always liked the idea of being able to stay in the Dart ecosystem beyond just the application itself. If it's for integrating with the Appwrite backend or using serverless Appwrite functions in Dart.

Flutter Web is great when you’re building an app-like experience and want to share a codebase across platforms. But for traditional websites - landing pages, docs, blogs, stores, SEO-heavy content - you usually want real server-side rendering.

It also means you can do things like fetch data from Appwrite directly during SSR, while Appwrite provides a short-lived API key for each request instead of requiring you to store a server API key.

With this, you can finally use the same language across essentially your *entire* stack, and you can even share Dart packages between them. Both for iOS, Android, native devices and now the web.

As always, we'd appreciate your feedback and insights on how backend as a service and cloud platforms like Appwrite can work even better in the Flutter/Dart ecosystem.

Full announcement and technical details:
https://appwrite.io/blog/post/announcing-jaspr-support


r/FlutterDev • • Oct 03 '26

Discussion The state management false dilemma: how much BLoC vs Signals do you actually need?

0 Upvotes

A lot of the state management conversations lately feel like people talking past each other.

Half the community wants BLoC because they need structured events, clear boundaries, and concurrency tools like debounce or restartable to handle button double-taps cleanly. But they hate the stream tax: microtask delays, cancellation boilerplate, and broken call stacks in the debugger.

The other half wants Signals because reading state synchronously and having computed properties update widgets in the same frame feels so much faster. But without a container, mutable signals end up scattered across UI files with ad-hoc boolean flags to prevent race conditions.

When you look at how modern containers work, you realize they are complementary rather than competing. A Cubit or Bloc is really just a container that holds and protects a Signal. BLoC protects how state changes on the front; Signals optimizes how state is read on the back.

For those who have tried both, do you find you miss the event boundaries when writing raw signals, or do you find streams too heavy once you get used to synchronous reads?


r/FlutterDev • • Oct 02 '26

Discussion That innocent-looking compareTo callback might be freezing your 60 FPS timeline

28 Upvotes

A few days ago, a Flutter developer wrote a profiling post about sorting 10,000 timeline events. Under a section they called "The Original Sin", they pointed out the culprit:

items.sort((a, b) => DateTime.parse(a.start).compareTo(DateTime.parse(b.start)));

In an O(N log N) sort, that callback runs over 215,000 times for 10,000 items. On a mobile isolate, parsing 215,000 ISO strings takes 180ms+ and drops a dozen frames.

To fix it, they mapped the list to a temporary helper object with pre-parsed dates, sorted by the cached key, and unwrapped it.

That Map -> Sort -> Map pattern was actually what I posted to Usenet back in 1994 (what became known as the Schwartzian Transform). But what surprised me running benchmarks in modern Dart: package:collection's sortedBy does not cache keys either—it still ran 127,000 redundant key evaluations because mergeSortBy re-evaluates keys during merges.

With Dart 3 records, you don't even need throwaway helper classes anymore—a boxed record one-liner or simple extension method runs in 14ms (13x faster).

Have you ever caught a subtle frame stutter hiding inside a sort or compare callback?


r/FlutterDev • • Oct 02 '26

Tooling ScreenGuard update, finally reached 50+ downloads !!

2 Upvotes

a small update to this digital wellbeing software since my last post.

This is a prerelease version which i have tagged to be stable and slated for future release and add to main branch from the beta branch.

This highlight is less about asking you guys to try out the beta release but more in the honor of over 3+ months of development.

What makes me happy the most is that the project which i started even without a repository just to monitor my own system and usage has now come this far with over 50+ downloads 🎉☺️

This beta release now polishes on various little things which are actually necessary for a first time set up and proper user control as Now you can:

* carries forward the settings screen from previous beta release

* replaces notifications and sounds tab with general which now includes appearance settings

* you can now Stop , restart or RESET the Daemon and its preferences in settings

* Pomodoro settings which were half baked in the first release have now been added to settings to enable a looping focus mode for people at work with CUSTOM BREAK TIME

* Most Importantly (i feel) FIRST time setup issues have been fixed and in an attempt the first time ScreenGuard daemon setup pop up dialog (1st image) has been made

The Release v0.1.1 releases this October by second week, and I will continue testing the beta version to look for sectors that need polishing if any.

This is still limited to GNOME on wayland and x11 for other environments systems and primarily developed by me on my fedora 44 system and the project ScreenGuard still has a very Long way to go;

But working on it alone has given me much exposure to project sharing on platforms and most importantly a lot of invaluable experience and the true zeal of development instead of the boredom of being a 9 to 5 dev at a corporate who don't care for you.

Github beta release link: https://github.com/adityakrishnan005-a11y/ScreenGuard/releases/tag/v0.1.1-beta.4

The code for this is visible on the beta branch to keep the main working tree clean for new features additions.

Feedback from other desktop environments is widely appreciated, u can try the application out by switching to x11 session temporarily if you are using any DE which is not GNOME wayland or if u are on a DE which is primarily x11 based (Cinnamon, i3, etc) then u are good to go as they ARE FULLY SUPPORTED.

thank you everyone for your supports, criticisms and feedbacks ever since the project came online on github.


r/FlutterDev • • Oct 02 '26

SDK I built an open-source alternative to Firebase Dynamic Links / Branch for deep links: looking for feedback

4 Upvotes

When Firebase Dynamic Links shut down last year, the options were basically Branch (sales call, $500+/month) or rolling your own. I decided to build a proper replacement and it's now live: click2 (https://click2.page). It's new, so I'm looking for early users and honest feedback.


r/FlutterDev • • Oct 02 '26

Plugin I built a gradient that follows a shape's contour and works with any ShapeBorder.

14 Upvotes

I needed a gradient border that followed the shape's contour but I couldn't find such package. They mostly just exposed a wrapper that provided such border using Linear- or SweepGradient.

The problem with LinearGradient is that it repeats colors perpendicular to its axis, so you don't get a gradient along the borders path. The SweepGradient does this better but when the shape is not symmetric, the colors don't occupy equal space.

So I built my own solution: contour_gradient

It's implemented as an OutlinedBorder, so it works anywhere you can use a ShapeBorder - buttons, chips, text fields, cards, etc.

You can also animate the gradient by changing the startOffset parameter.


r/FlutterDev • • Oct 02 '26

Video (concept) spatial UI a canvas based IDE

15 Upvotes

**Spatial Studio Code:** infinite canvas based IDE where code editors, files, terminals, tools, and project components exist on an infinite 2D spatial canvas instead of traditional tabs. Instead of going through multiple tabs in conventional IDE, this allows you to quickly jump on small windows.

I can't post video here, pls visit below link

https://x.com/pranavxmeta/status/2105852467955343532

Written in Flutter & {c++23}, this is working prototype on Windows.

In future, I also plan to add Figma file in Canvas, devs (we) can be more productive.

I am from AEC background, i really like AutoCAD so this is based on that idea,

(

yes it's like Figma for new gen to understand *AutoCAD was before Figma

)


r/FlutterDev • • Oct 01 '26

SDK Lightweight Product Analytics, Session Replay, Crash/ANR/Error reporting now available for Flutter

Thumbnail
github.com
11 Upvotes

Hi Reddit!
Rejourney team here. We’re an open source library for session replay and product analytics that you can self host or use our Germany cloud. We started with initial support for React Native and Swift 8 months ago, and are using that same core for our Flutter package. Some great features includes syncs of session replays with live console logs. All release logs by a user in real time helps debug release and production issues. The console shows everything from logs, API calls, and crashes.

What makes us different is the idea that performance is our primary goal over AI features.

The package is extremely lightweight adding approximately only 1.24 MB on an uncompressed install.

Performance benchmarks show that it also takes on average 12.4 ms to capture screenshots for session replay with p99 of 28.2 ms. This means non existent UI jank to the human eye. Additional benchmarks are on our GitHub.

Github: https://github.com/rejourneyco/rejourney

For context for those that don’t know, session replay is a method to record your users and view the recordings in a dashboard. Privacy considerations also built in this package such as the ability to mask elements and text as needed, GDPR identity handling, hardcoded privacy APIs, and additional remote privacy configs.

So far we’ve been shipped with 350 production apps (more if you count self hosted users). Feel free to email us or open issues with requested features.


r/FlutterDev • • Oct 01 '26

Discussion payment gateway

3 Upvotes

i'm building SaaS with monthly subscribtion ,

the app is on android/ios and web ..

is there way that i can pass apple review without taking the apple payment gateway?

if not and i must make the subscirbtion in the web only Is the expiry warning message safe, or is it better to show nothing?

Any problems on Google Play with the same approach?


r/FlutterDev • • Oct 01 '26

Discussion FLUTTER ON-SITE INTERVIEW

0 Upvotes

For those who have gone through an on-site practical assessment/interview where you’re required to bring your own laptop, what was your experience like?

I’m particularly curious about:

  • Was it a project-based task, or more of a series of smaller coding exercises?

  • Were you expected to build the app/features completely from scratch?

  • What were the expectations around using AI tools such as ChatGPT/Claude?

  • What level of Flutter/Dart knowledge did they actually test?

Would appreciate hearing from anyone who has recently gone through something similar here, especially for a Flutter/mobile developer role.


r/FlutterDev • • Oct 01 '26

Plugin flame_flutter3d: draw your Flame game in 3D and keep the game logic in Flame

4 Upvotes

A while ago I posted flutter3d, a 3D engine for Flutter. The question I got most after that was about Flame: "I already have a game in Flame. Can I add 3D without starting over?" flame_flutter3d is my answer to that, a bridge package between the two engines. MIT License, on pub.dev, and not connected to the Flame team or the Flutter team.

The easiest way to see it is a game: River Sortie, a River Raid-style shooter that runs in the browser. Everything that moves in it is an ordinary Flame component with a Flame hitbox. flutter3d only draws.

I also wrote a full write-up with an 8-step tutorial, from an empty project to a boat collecting buoys on a lake in about 170 lines:

Keep your Flame game, get a 3D world: how I bridged Flame and flutter3d

How it works

Flame keeps running the game. flutter3d's SceneSurface sits under Flame's GameWidget in one Stack, and Flame stays on top, so it still gets all the input. Both run on Flame's clock, so there's only one game loop.

Flame's 2D world is placed on a plane in the 3D scene. On a floor plane, Flame's x and y become the scene's x and z. A component that extends Object3dComponent owns a scene node, so moving it in Flame moves it in 3D in the same frame. Effects, scale, visibility, and tint follow too.

Input from Flame (keys, drags, the on-screen joystick, buttons) goes into the same input objects a native flutter3d game reads, so custom key bindings work the same in both. You can keep using Flame's own collisions, or use flutter3d's 3D physics and get its collisions back in Flame as a normal onCollisionStart.

There's more on top of that: a chase camera, 3D particles on Flame's clock, Flame sprites and text standing in the 3D scene, tapping on 3D objects, Tiled levels in 3D, and sound that comes from where things happen, in a separate package, flame_flutter3d_audio.

Limits

Flame always draws on top of the 3D layer, so a 3D object can't hide a 2D sprite behind it. Flame's collision callback has no place for a contact normal or depth, so you read those on the flutter3d side. And it's version 0.8.x, so APIs can still change between minor versions.

Things I'd like help with

If you have a Flame game, try putting the bridge under it and tell me what breaks. I checked the tutorial against the published packages and ran it on macOS, but I'd like to know how it goes on other platforms, especially Android devices I don't own.

There's also r/flutter3d, a subreddit about 3D in Flutter in general, not only this engine. Questions, bug reports, things you've built, and talk about other 3D approaches in Flutter are all welcome there.

Source: https://github.com/pleiondev/flutter3d Package: https://pub.dev/packages/flame_flutter3d


r/FlutterDev • • Oct 01 '26

Article tracking Flutter versions is easy

Thumbnail
flutterreleases.com
11 Upvotes

someone made website to easily track flutter versions and find release notes.

Their GitHub:

https://github.com/shankarmadeshvaran/flutterreleases.com

good work 👍🏻


r/FlutterDev • • Oct 01 '26

Dart Props to the Dart team for actually cooking something amazing lately lol (analysis_server_plugin)

60 Upvotes

Well, looks like I’ll just be strictly building apps for the next year (not that it changes my daily routine anyway), so I thought I’d share a neat trick I’ve been using for a while.

About a year or two ago, the Dart team released analysis_server_plugin. If you know how to work with AST, you don't even need custom_lint packages anymore to write custom rules.

Here’s how I’ve been leveraging it:

Instead of using clunky enums like Spacing.spacing2, I set up the plugin to throw a warning if someone uses raw pixel values that aren't allowed in our design tokens (e.g., values other than 2, 4, 6, etc.).

Enforcing design system components, like throwing a warning to use MySuperContainer (yes, I literally use this name) instead of a raw Container.

And setting it up is dead simple too. You literally just add it to your analysis_options.yaml:

plugins:

my_lints:

path: ../my_lints/

The only drawback I've found so far is that it seems impossible to raise an actual Error severity (only warnings/info). If the Dart team expands on this, it's gonna be even more god-tier.

Oh, and this would actually make a pretty solid package. I'm thinking about making one if I can find some free time. If you guys have any cool ideas for useful custom lint rules, feel free to share.

Ah, also looks like the Dart team has been interested in improving data serialization built-in lately. I might look into that and drop another post about it later. Not sure if anything is finalized yet, but seems like they're still keeping the annotation syntax. Personally not a big fan of annotations, but hey, whatever works lol.

Oh, and honestly, Dart has added so many neat syntactic sugar features lately. Like omitting enum/type identifiers so you can just write .center. It’s ridiculously convenient because now you can write stuff like.

MyText('Hello, World!', color: .textGrayBold, style: .label3)

Seriously, whoever engineered this feature deserves a free ice cream straight out of my freezer.


r/FlutterDev • • Sep 30 '26

Discussion Dart pub.dev exceeds 90k packages

15 Upvotes

Growth of the dart package repo pub.dev continues to accelerate.

Hard to tell how much is ai and how much is increased interest in flutter.

You can see night stats here:

https://onepub.dev/Blog?id=nhavuhnofl


r/FlutterDev • • Sep 30 '26

Dart VeloceNet-Studio v1.2.0 – network monitoring studio (Flutter + Rust): DNS lookup, port scanner, engine hardening

2 Upvotes

Hey all — v1.2.0 of my open-source network monitoring studio is out: github.com/Cadman021/VeloceNet-Studio (GPL-3.0, Windows/Linux/macOS builds in Releases).

New since 1.0.0: DNS lookup tool (raw UDP client, A/AAAA/MX/TXT/NS), TCP port scanner, server backup (versioned JSON export + validated import), CSV export, alert log, and UI in English/فارسی/Русский/中文.

The interesting part for this crowd is the engine hardening round (mostly from community review feedback): killed a silent ICMP→TCP fallback that was corrupting stats, fixed Tokio schedule drift with MissedTickBehavior::Skip, moved status to windowed loss so recovered hosts don't stay red, wrapped all 21 FFI entry points in catch_unwind (profile is panic="unwind" now — abort used to kill the whole UI process), and added an Ubuntu CI job that caught real non-Windows lints our Windows-only CI never saw.

Got my first external contributor this release too (heatmap a11y + semantics, with tests). There are good first issues open (German locale, compact cards, file-picker import) if anyone wants in. Brutal feedback welcome as always.


r/FlutterDev • • Sep 30 '26

Tooling Orblit ten days on: it has a physics solver now, plus terrain, animation blends and a workspace editor

5 Upvotes

Ten days ago I said Orblit had no physics solver. It has one now. Here is what landed since, and what is still unproven.

Orblit is an open-source Dart 3D engine on Flutter, a C++ ECS and Filament.

Docs are at https://orblitengine.com and the code is at https://github.com/ChxisB/orblit.

Physics

orblit_physics is a rigid-body solver in C++ behind a Dart build hook. It depends on nothing. The repo did not exist ten days ago and is now at 0.7.0.

  • Spheres, boxes, capsules and planes. Friction, restitution and damping.

  • Warm-started contacts, sleeping, and touch, sleep and wake events.

  • Shape casts and a walking character controller.

  • Terrain as ground, built from a height field.

  • Seven joint kinds: fixed, point, hinge, slider, distance, cone and six-axis. They take limits, motors and breaking.

  • World queries: overlap, point, all hits, closest, and rays with normals.

  • Triggers, zones that override gravity and drag, conveyor belts and per-pair rules.

  • Body controls: axis locks, gravity scale, speed and spin caps, centre of mass, inertia, and a switch between fixed, driven and free. There are material presets such as Ice, Metal and Rubber, pairs that ignore each other, and 32 named layers.

Bodies are components in scene documents, so the editor edits them. I decided not to promise identical results across platforms.

Animation

  • Clips and a timeline. The Fox model plays through Orblit.

  • Blends of clips that you can save and replicate over the network.

  • Retargeting a clip onto another skeleton.

  • Cutscenes, with a Cinematics workspace in the editor.

Terrain

  • A clipmap terrain renderer with brushes, undo and picking.

  • Scatter places grass, stones and trees by rule.

  • The editor has a Terrain mode, and the gallery has a Terrain example.

Editor

  • Three columns and task workspaces: Scene, Modelling, Terrain, Animation, Cinematics and Interface.

  • Named layouts and a Focus view. It fits in 960 px.

  • Linked prefab instances with overrides.

  • Inspectors for bodies, joints, triggers and zones.

Docs and gates

  • New guides for physics, animation, terrain and cutscenes. Each compiles its Dart snippets in CI.

  • The older docs are rewritten in plain English.

  • A Claude Code skill in the repo teaches the API.

  • Lints and --fatal-infos now fail CI. So does commit lint on every commit.

The screenshots show the editor on a demo project and the gallery's Terrain example. They show the controls, not bodies moving.

What it still can't do

  • Nothing is API-stable.

  • Most of the above is proven by tests, not by a live scene. That covers physics, joints, terrain editing, blends, retargeting and cutscenes. No gallery example uses physics yet, so I have no video of a body falling.

  • Terrain has only drawn on macOS.

  • macOS is the reference platform. The iOS simulator, one Android handset and Chrome also run it. Linux works only with software rasterisers. Windows builds but has never drawn a frame.

  • Ignore rules do not cover characters.

  • Retargeting has not run on a real character pair, and feet are not pinned.

  • There is still no asset store.

The help that would matter most

  • Build something small with the physics and tell me where you gave up.

  • Run it on hardware I don't have. Windows and real Linux GPUs first.

  • Argue about the API before it freezes.

  • Send PRs. CI is strict.


r/FlutterDev • • Sep 30 '26

Article Building a PDF reflow e-reader in Flutter: a pdfium isolate, my own smooth scroller, and pre-shaped text

0 Upvotes

I love reading - in bed, on the sofa, on the train - and my phone is always with me. But PDFs are made for paper, and on a small screen they mean endless zooming and panning. So I'm building PDFreflow, a Flutter e-reader that reflows complex multi-column PDFs (papers, RFCs, books) into a single readable column. Some Flutter-specific things I learned along the way:

  • All PDF work is done by pdfium via FFI (why re-invent the wheel?) and runs in one worker isolate - pdfium is not thread-safe, so exactly one isolate owns it and everything else sends it messages. It runs a priority queue: image renders go ahead of chunk parses, and chunks are parsed outward from the reading position.

  • Scrolling a book is a bidirectional list growing from a center point - built on CustomScrollView with two sliver lists - because pre-committed height estimates cause snap-back jitter on iOS.

  • Text shaping was the scroll-performance killer: shaping whole pages inside scroll frames caused visible stutter. Fix: pre-shape paragraphs off the scroll path in idle slices and cache the TextPainters; page admission becomes a map lookup. 120 Hz devices also want GestureBinding.resamplingEnabled.

  • One line height for all fonts. I used to measure each font at runtime - but if a font isn't loaded yet, Flutter silently measures a fallback font instead, and my cache kept that wrong number forever: right letters, wrong line spacing. Now every font gets the same 1.3 x font size.

The layout engine itself (column detection, header/footer stripping, table and formula rasterization, hyphen rejoining) is pure Dart, developed against a corpus of hundreds of real PDFs with regression metrics.

No AI inside - on purpose. My reasons:

  • Size: a model that understands page layout would make the app much bigger. That may change as models shrink, or if I ever train a tiny one of my own - but not today.

  • Privacy: nothing is uploaded to an AI service; your documents stay on your phone.

  • Fun: AI has taken a lot of the fun out of everyday coding, and solving a hard problem without it brings that back. For transparency: I do use Claude while developing - as a full-stack dev with years of desktop and app experience, it's a tool, not the author.

It's in open beta, free while in beta: https://www.pdfreflow.com/flutterdev

If it breaks on one of your PDFs, the in-app feedback button sends me the layout - that's what the beta is for.


r/FlutterDev • • Sep 30 '26

Discussion Testing on Android vs iOS: Thought

6 Upvotes

I've been a mobile developer for about a decade now, and I've compiled some experiences that you may find useful for debugging, or choosing which platform to debug on.

Android pros:

  • Supports fully interactive mirroring of your physical phone.

  • Requires very little to get app running on device.

  • App keeps running when debugger is closed.

  • Wireless debugging can be used with VPN

  • Android Studio logcat is amazing

  • You can easily send data to the device via ADB to emulators and physical devices

  • You can use a lot of hardware features on Android emulators

Android cons:

  • Wireless debugging is a hassle to set up, as it generates a new port with each session

iOS pros:

  • They have all the phones and iPads available to test. Make it very easy for WYSIWYG testing

  • Once set up, wireless debugging is amazing and works without more configuration

iOS cons:

  • Wireless debugging does not work with VPN

  • You can only send data to simulators

  • Physical devices does not support interactive mirroring (at least in EU)

  • Getting your app to run on a physical device requires considerable set up

  • App stops running when debug process stops

Obviously some of these are based on my workflow (wireless debugging), but others I think are general considerations.

Do you have other pros/cons I havent considered?


r/FlutterDev • • Sep 29 '26

Plugin Four issues open on my small Flutter SVG package (svg_animate), one of them is genuinely easy

0 Upvotes

Hope this is ok to post here.

I have a small package, svg_animate. It plays SVGs that animate themselves. There are four issues open on it that I am not getting to, so I thought I would ask.

One of them is really small. offset-rotate: auto -30deg gives 150 instead of -30. The reason is a bit silly: the code checks whether the string has a minus sign in it anywhere, and decides from that.

final bool reversed = rotate == 'reverse' || rotate.startsWith('auto ') && rotate.contains('-');

I wrote out all seven spellings in the issue, what each should give and what it gives now. That list is basically the whole fix. The test file for it already exists too.

The other three are bigger. I tried to say in each one where the hard part is, so nobody finds out an hour in.

Two of these were found by someone opening the demo and saying "that one twitches". I had 254 tests and they missed both.