Scaling UI development at Change with Sandcastle

Tobias Butler
Making Change.org
Published in
5 min readFeb 3, 2021

We had a problem. Maybe you’ve seen it before. Our legacy frontend was so big. Sometimes we’d want to make a small visual change to a component, but doing so required us to start our whole development stack and wait for slow Webpack rebuilds of the whole application. We just wanted to make a button bigger — why did it have to take so long?

The solution to this problem started with a simple dream — what if you could point your web browser directly at a component file, and view that component in your browser? Could that be possible?

A representation of loading a UI component directly in a web browser.

Centralized sandboxes — and their limitations

One of our teams here at Change had demonstrated that they could iterate faster by using a custom Webpack config to create a page with all their React components on it, each one populated with fake data for testing. This helped speed up the process for their team, but we realized it would soon run in to scaling issues even if just used on one team — components would pile up on the page, the bundle would get larger and larger, and it would get harder to focus on a single component.

Sandboxing and documentation tools like Storybook and Docz have good structures for organizing your components, but they have some of the same issues with scalability — the more components you have, the bigger (and slower) your sandbox site gets. We wanted a solution that would only include the Javascript necessary for a single component — no more, no less.

The answer came after piecing together Express and Webpack to create something we call Sandcastle — a sandbox that stays robust no matter how many components your app has.

A castle with parapets made of UI components.
Photo by Zakaria Kasmi on Unsplash

Sandcastle, the decentralized multisandbox

The secret of Sandcastle is in creating a dynamic Webpack configuration when a component is requested. When you load a page from the Sandcastle server in your web browser, it looks for the right component to display based on the path you entered. Then, it creates a webpack configuration just for that component by changing Webpack’s entry field to only include that component and any necessary dependencies (in particular, React contexts).

A diagram showing individual URLs on Sandcastle mapping to individual instances of Webpack middleware.

That configuration is used to create an instance of webpack-dev-middleware to serve that component. All of the development features of Webpack — building the JS/TypeScript files, serving requested assets, even hot reloading — are available, with special routes specific to the component to ensure we’re only building the minimum bundle for each component.

We had what we wanted — a way to put the path to a UI component in the browser and see it on your screen. Already we were iterating on our components faster, hot reloading our changes without a heavy dev environment. We even built a special homepage for Sandcastle to search for component files in the browser and access recently edited files. But what surprised us all was the unexpected ways our process started to change due to this new tool.

New tools, new processes

One early advancement had to do with our approach to responsive design. Sandcastle lets you define custom layouts that change how your component is positioned on the page. One clever engineer realized that you could make a layout that rendered the page in iframes for every browser breakpoint at once. No more excuses for forgetting to test a feature on mobile when making a visual change.

A petition card component shown at multiple breakpoints on a single page.

We also found that we could change the way we released our work. If you can develop a component in isolation, you can create smaller tasks and help complete more work in parallel. Rather than wait until we could integrate a full feature with our frontend, we could build one part of the feature and test it with Sandcastle. This has the added benefit of avoiding merge conflicts when multiple people are starting work on the same feature.

A diagram showing how doing more work in parallel and integrating it at the end of the process can speed up development.

The future of the castle

We’ve got even more future plans for Sandcastle. Even though we are in the process of replacing our legacy frontend with something lighter-weight, we still find Sandcastle useful to isolate our UI components during development. We’re also hoping to create a deployable version of Sandcastle, so that designers, PMs, and QA engineers can validate component behavior on their own computers—particularly important while we’re all working remotely. Because Sandcastle creates pages that don’t depend on other services, it will be easy and cheap for us to make a deployed Sandcastle environment for every branch.

Hackers are famous for being able to improve their own tools — it’s one of the major drivers of the open source community, and it’s the principle driving the tech behind the famous “Mother of all Demos”. But building Sandcastle showed us something more: when you work to change your tools, sometimes those tools will change the way you work. We’re excited to see what new ideas will spark a revolution in how we work.

Change.org is hiring a staff software engineer to push the boundaries of UI development to create social change. You can read our job posting and others like it on our Careers page.

--

--