House cleaning - starting with the datepickers

Every codebase has that corner. You know the one. The drawer you don't open. The files you scroll past a little faster. The thing that...

Pedro Martins
Pedro Martins
Share:

Every codebase has that corner. You know the one. The drawer you don't open. The files you scroll past a little faster. The thing that works, but you'd rather not talk about it.

For Backpack, one of those corners was datepickers.


Three fields, three libraries, three headaches

If you've been around Backpack for a while, you know the situation. We had:

  • date_picker - powered by bootstrap-datepicker (with moment.js)
  • datetime_picker - powered by bootstrap-datetimepicker (also moment.js)
  • date_range - powered by bootstrap-daterangepicker (yes, moment.js again)

Three different JavaScript libraries. Three different sets of options. Three different format tokens. Three different ways to configure basically the same thing: pick a date.

And moment.js? Let's be honest, it's been "dead" for years. The project itself tells you to stop using it. But there it was, bundled into Backpack, quietly adding weight to every page load.

It wasn't broken. It worked. But it was messy. And messy things don't age well.


Enter air-datepicker

With v7.1, we're doing something about it. We're introducing a single field to replace all three: air-datepicker.

air-datepicker is a modern, lightweight (~13KB) JavaScript datepicker. No jQuery dependency. No moment.js. Just a clean, fast, well-maintained library that does everything we need.

One field. One set of options. One way to format dates (Unicode TR35, if you're curious). Whether you need a simple date, a datetime, or a date range, it's all the same field:

// A simple date
CRUD::field(['name' => 'published_at', 'type' => 'air-datepicker']);

// With time
CRUD::field([
    'name' => 'published_at',
    'type' => 'air-datepicker',
    'air-datepicker' => ['timepicker' => true],
]);

// A date range
CRUD::field([
    'name' => ['start_date', 'end_date'],
    'type' => 'air-datepicker',
    'air-datepicker' => ['range' => true],
]);

That's it. No more remembering which field type handles what. No more looking up whether this one uses format or dateFormat or something else entirely.

And the old fields? They're still there, but they're marked as deprecated. They'll be removed in the next major version (probably). You have plenty of time to migrate, and honestly, the migration is just changing the type and renaming a few option keys.


Why this matters

This isn't about adding a shiny new thing. It's about cleaning up. Every line of code we remove is a line we don't have to maintain. Every library we drop is a dependency that can't break. Every duplicated feature we consolidate is one less thing for you to think about when building your admin panel.

The old datepickers served us well. Bootstrap-datepicker was there since the early days. But software moves on, and maintenance has a cost. The longer you carry old code, the heavier it gets.

Before (v7.0) After (v7.1)
3 field types (date_picker, datetime_picker, date_range) 1 field type (air-datepicker)
3 JS libraries (bootstrap-datepicker, bootstrap-datetimepicker, bootstrap-daterangepicker) 1 JS library (air-datepicker, ~13KB)
Requires jQuery + moment.js Zero dependencies
3 different option formats 1 consistent config
~200KB of extra JS ~13KB

This is just the start

Datepickers were the obvious first target, but they're not the only corner that needs attention.

Next on the list: select2.

If you've ever peeked inside the Backpack field templates, you know what I'm talking about. We have select2, select2_multiple, select2_from_ajax, select2_from_ajax_multiple, select2_grouped ... and they all do variations of the same thing. Different blade files, different JavaScript, different configurations. But underneath, it's all select2.

We're looking at two paths here: either consolidate these into fewer, smarter fields that share more code, or, like we did with datepickers, look for a modern alternative that can handle all the use cases in one clean package.

No decision yet. But the datepicker cleanup gave us a template for how to approach this. Find the mess. Pick the right tool. Make it simple. Give people time to migrate.

House cleaning is slow work. You don't do it all at once. But you have to start somewhere. And datepickers felt like a good place to begin.


What you need to do

If you're on Backpack v7.1, nothing breaks. The old fields still work. But when you have a spare moment, try swapping one of your datepickers to the new air-datepicker type. Change the type, update the option keys, and you're done.

You'll get a faster field, a smaller bundle, and one less deprecated warning to worry about.

And hey, clean code feels good. Even when it's not yours.

Want to receive more articles like this?

Subscribe to our "Article Digest". We'll send you a list of the new articles, every week, month or quarter - your choice.

Reactions & Comments

What do you think about this?

Latest Articles

Wondering what our community has been up to?