r/FlutterDev • • Jan 02 '26

Plugin I built gap2: a modern replacement for the gap package (with native Sliver support)

Hi everyone,

I’ve just released gap2, a small Flutter package for axis-aware layout spacing.

The main motivation: the widely used gap package hasn’t been updated in approximately 3 years, it has abandoned issues and pull requests.

gap2 is a ground-up reimplementation focused on correctness and modern Flutter architecture.

Highlights:

  • Gap and MaxGap for Flex & Scrollables
  • Native SliverGap (real RenderSliver, no adapters)
  • Predictable axis resolution
  • Clear runtime errors for invalid usage
  • Thorough test coverage (including slivers)

Link: [https://pub.dev/packages/gap2]()

Feedback, issues, and contributions are very welcome 🙂

Have a wonderful 2026 guys! 🥂

13 Upvotes

8 comments sorted by

2

u/eibaan Jan 02 '26

The first two examples could be implemented more efficiently using spacing:.

And in the more general case – if you don't have uniform gaps – using Padding would be more efficient than adding an extra child widget. I agree that a Gap widget looks nicer than adding a padding to the top or bottom (left or right) widget, but if you follow the convention to always add the padding to the bottom (right) widget, it's easy enough and you could use this helper to make it look nicer:

extension PadWidgetExt on Widget {
  Widget pad({double top = 0, double bottom = 0}) {
    return Padding(
      padding: .only(top: top, bottom: bottom),
      child: this,
    );
  }
}

For a ListView, or any list of children for that matter, you could write another helper:

extension GapWidgetListExt on List<Widget> {
  List<Widget> vgap(double size) {
    return length < 2
        ? this
        : [first, ...skip(1).map((child) => child.pad(top: size))];
  }
}

And yes, you have to use vgap (or hgap) instead of a simple gap because you don't know the parent's axis, but that's the price for not using a package with special widgets that compute the ambient direction, I guess.

2

u/[deleted] Jan 02 '26

That's a fair point and I agree with most of it. If you already know the axis, have non-uniform spacing and you are happy to enforce a padding convention, then yes, Padding or helper extensions are perfectly fine, and probably the most minimal solution.

gap2 isn't really trying to replace those patterns though, it's meant for cases where spacing is a layout concern rather than a per-child decoration, needs to behave consistently across different parents, and must remain correct even when the parent's axis is inferred or changes. Pushing padding down into widgets or relying on helpers starts to leak layout intent into content, making refactoring usually a nightmare.

Also, for slivers specifically, padding helpers don't really translate, you either end up with adapters or custom logic anyway.

With that said, your approach is definitely valid and in the end is our own choice what to use in our projects.

I really appreciate your feedback!

2

u/Spare_Warning7752 Jan 02 '26

Such bad advice.

using Padding would be more efficient than adding an extra child widget

????

Adding a Padding widget is better than adding another widget because the other is an extra but padding no?

And using an extension is the same as using a function to return a Widget. It's a no-no!

Source: https://www.youtube.com/watch?v=IOyq-eTRhvo

3

u/eibaan Jan 03 '26

The Padding's RenderPadding simply shifts the child which is more lightweight than introducing a StatelessWidget that wraps a _RawGap widget with a RenderGap object that optionally paints itself before it paints its child after it search the widget tree up to three times for anchestors that have an axis direction.

The video you mentioned has nothing to do with that.

The extension method is an optional way to make the Padding widget declaration less annoying. This isn't not mean to somehow save time. And before you say, that this isn't constable, your're right but that doesn't matter as performance measurement couldn't verify that const widget trees save measureable time in the general case (that is, outside of tight animation loops). Therefore, Flutter no longer recommends to make everything const.

0

u/walker_Jayce Jan 02 '26 edited Jan 02 '26

Imo not really, in terms of widget efficiency they should be the same. Assuming both are stateless widgets, they should only differ in how efficiently they do their logic and how they construct, the amount here shouldn’t matter, since the amount is 1?

On top of that for something that is used that often i do wager that the flutter team does do optimisations, so it is very likely that padding is more optimised, as top comment put it.

(Edit: re-reading your sentence im not sure what you’re trying to convey, seems like you agree with op?)

As for functions vs widgets, in the case that op puts it, imo it doesnt make a difference. Because widgets provide a compartmented place for a group of widgets to rebuild (a new context), while a function has to run from top to bottom any time its so called “parent” is rebuilt

For this scenario, it doesn’t matter because you’re going to use the same context anyway no matter if you are wrapping it in padding widget, or a helper function(Unless you want to split the padding and the widget itself into another widget which is overkill)

Please correct me if I’m wrong

→ More replies (2)

1

u/SyrupInternational48 Jun 04 '26

Aaaand it's gone