ShapeKit
← Back to Blog

Why Giving Users Dashboard Control Is Harder Than It Sounds

Schema drift, multi-tenant isolation, constraint enforcement, and performance — the four walls every team hits when building user-configurable dashboards.

By ShapeKit Team

Every developer who has shipped user-configurable dashboards has the same scar.

It usually starts with a reasonable request: "Let users choose which columns they want to see." So you build it. A user preferences table, a settings modal, some client-side render logic. Two days. Done.

Then it gets complicated.

The problems that don't show up until you're in them

1. Schema drift

Your data model was designed for a fixed view. Users don't know that. They want to surface fields that don't exist yet, combine data from tables that were never meant to join, and filter on columns that weren't indexed because nobody was supposed to query them.

The first request was easy. The tenth request requires a schema migration. The fiftieth requires you to rethink whether your original data model was right at all.

2. Multi-tenant isolation breaks in unexpected ways

In a single-tenant world, user customization is a settings page. In a multi-tenant SaaS product, it's a minefield.

User A in Company X customizes their dashboard. User B in Company X should see... what? Company X's defaults? Their own settings? A merge? Who wins when there's a conflict?

Now add roles. An admin in Company X wants to set a base layout that users can modify within certain bounds. Users can add columns but can't remove mandatory ones. Column ordering is user-defined, but column visibility is admin-controlled.

You're not building a settings page anymore. You're building an authorization system layered on top of a configuration system layered on top of your actual product.

3. Constraint enforcement is hard to get right

The most underrated problem: users who are allowed to customize will push outside the bounds you intended.

If you let users add columns, what happens when they add 47 columns and your table renders broken on mobile? If you let users reorder widgets, what happens when they move the warning widget off screen and miss a critical alert?

Unconstrained customization creates support tickets. It also creates liability — "the dashboard told me everything was fine" is a bad answer when the dashboard was missing the widget that says otherwise.

You need a model that lets users shape their own view within guardrails you define. That's a different problem than "let users customize." It requires a different architecture.

4. Performance degrades as configurations multiply

A fixed dashboard query is fast. An optimized query against a predictable schema, cached, indexed. A user-configurable dashboard query is a variable. If users can show or hide columns, filter on arbitrary fields, and sort by any attribute, you've made your query surface area exponentially larger.

The first hundred users don't reveal this. The first thousand do.

Why teams keep building this from scratch

Every developer who has shipped this kind of system eventually asks: why isn't there a library for this?

The answer is that the problem has three layers that are rarely solved together:

  1. The UX layer — how users interact with the customization surface (drag-and-drop, settings modals, inline editing)
  2. The persistence layer — how customizations are stored, versioned, and scoped per user, role, and tenant
  3. The constraint layer — what you as the builder define as shapeable vs. fixed, and how violations are enforced

Most tools solve one. A drag-and-drop component library handles the UX. A JSON config store handles the persistence. But nobody tells you how to define the allowed shape space, or handles the multi-tenant isolation, or enforces the column limits.

So teams write the glue themselves. Every time. Which is why you've seen this exact code in three different codebases.

A better model: constrained shaping

The insight we kept coming back to: user customization fails when it's unconstrained. The pattern that works is when the builder defines what's shapeable and users fill in their preferences within that space.

You define: "This column is optional. These three are fixed. Sorting is allowed on any column. Maximum visible columns: 12."

Users shape: which optional columns they see, in what order, with what sort preference.

The constraint lives in your code. The preference lives with the user. Nobody gets a 47-column table. Nobody calls support.

This is the model ShapeKit is built around. Define what's shapeable. Let users shape it. Ship one dashboard instead of N.

ShapeKit launches April 15 — full product, no waitlist. Sign up for early access.


Next post: How agency client portals become customization sinkholes — and how to stop it. Publishing March 24.