DEV Community

Cüneyt Çakar
Cüneyt Çakar

Posted on

Building Spexop: A Journey in Design System Development

Hey there.

I wanted to share a bit about building Spexop, a design system that started as a personal project and has slowly grown into something I'm actually pretty happy with. This isn't a "how we built the perfect design system" post—more like a casual reflection on what I've learned along the way.

The Beginning

It started with my desire to build my own design system instead of trying to be an expert on existing ones. I was working on sensitive applications, and I needed something I could understand completely, control fully, and trust implicitly. Existing design systems were great, but they were someone else's vision—someone else's decisions about what mattered and what didn't.

I found myself reaching for the same patterns over and over again. Grid layouts, buttons, forms, cards—you know the drill. After the third or fourth time copy-pasting the same component code, I thought, "maybe I should just make a library for this."

So I did. I started with the basics: a Grid component, a Button, a Card. Nothing revolutionary, just components that worked the way I wanted them to work. I wrapped them up in a package, published it to npm, and called it a day.

Except it wasn't really a day. It was more like the start of something that would occupy way more of my time than I initially planned. But building my own design system meant I could understand every line of code, every design decision, every trade-off. And for the sensitive applications I was working on, that control mattered.

The Philosophy Shift

Early on, I realized that if I was going to build a design system, I should probably have some guiding principles. I didn't want to just create another component library that looked nice but didn't really help developers think differently about building interfaces.

So I started thinking about what mattered to me:

Primitives before patterns - Master the grid system first, then build complex things
Borders before shadows - Clean, minimal aesthetics with strong borders instead of heavy shadows
Typography before decoration - Use font weight for hierarchy, not lighter colors
Tokens before magic numbers - Everything should use design tokens
Composition before complexity - Build up from simple parts
Standards before frameworks - Use web platform fundamentals
Accessibility before aesthetics - WCAG AA+ compliance by default

These seven principles became "The Spexop Way." It sounds a bit pretentious when I type it out, but honestly, it's just the way I think about building things. And it's helped me make decisions when I'm not sure which direction to go.

The Component Library

Fast forward a bit, and I've got 60+ components. That number still surprises me when I write it down. It started with five grid primitives (Grid, GridItem, Stack, Container, Spacer), and then I just kept adding things as I needed them.

Navigation components came next—TopBar, Sidebar, Navigation. Then forms, buttons, cards, overlays. Each time I built something for a project, I'd think, "this could be useful for others too," and I'd add it to the library.

The interesting part, at least to me, is how the structure evolved. I started with a flat list of components, but that didn't scale well. Now components are organized by category: primitives, navigation, forms, buttons, cards, layout, overlays, display, settings, advanced, and animations.

The Theme System

The theme system was probably the most challenging part to get right. I wanted something that was flexible but not overly complex. I tried a few different approaches before landing on what we have now.

The current system uses CSS custom properties (CSS variables) for everything. You can define a theme as a JavaScript object, and it gets converted to CSS variables that components consume. It's simple, performant, and works with any CSS framework.

I've included 13 pre-built themes (tech, startup, healthcare, finance, ecommerce, etc.), but you can easily create your own. The theme generator can export to 29+ different formats, which is probably overkill, but it's useful when you need to integrate with different tools.

Going Provider-Free

One of the bigger architectural decisions was moving away from React Context providers. I know, I know—everyone uses providers. But I wanted something simpler, something that didn't require wrapping your entire app in multiple provider components.

So I built utility hooks instead. useToastUtil, useModalUtil, useThemeUtil, etc. They work standalone, without providers. You just call the hook and use it. It's a bit different from what most React developers are used to, but I think it's cleaner.

The migration from providers to utilities was a bit of a pain, but I think it was worth it. The API is simpler, and there's less boilerplate. Plus, you can use these utilities anywhere in your app without worrying about provider hierarchy.

The Icons Package

I didn't plan on building an icons package initially. But I needed icons for the components, and I didn't want to force people to use a specific icon library. So I created @spexop/icons with 269 icons.

It's not the biggest icon library out there, but it covers the basics well. Each icon has a filled variant, and I've included some brand icons too. They're all SVG-based, tree-shakeable, and fully typed.

The CLI

At some point, I realized that getting started with Spexop could be easier. So I built a CLI tool that scaffolds new projects. You can run npx @spexop/cli create my-app and get a fully set up project in seconds.

It's not a huge feature, but it removes friction. And removing friction is one of those small things that can make a big difference in developer experience.

Developer Tools

I've also been working on some developer tools around Spexop. There's a VSCode extension (still at version 0.0.1, so it's early days) that provides code snippets and IntelliSense for Spexop components. It's available on the VSCode Marketplace, but it's still a work in progress.

I'm also building an MCP (Model Context Protocol) server for Spexop, though it's not published yet. The idea is to make it easier for AI assistants to understand and work with Spexop components. It's one of those side projects that might be useful, or might just be me overthinking things. We'll see.

Speaking of AI assistants, I've been working with them quite a bit for haste. They're great for getting things done faster, especially when you're building something as large as a design system. I can focus on the big decisions and architecture while letting AI handle some of the repetitive work. It's been a game changer for productivity, honestly.

What I've Learned

Building a design system is harder than I thought it would be. Not because the code is complex (though some of it is), but because of all the decisions you have to make. Every API choice matters. Every naming convention matters. Every breaking change affects real people using your library.

I've made mistakes. I've deprecated features. I've changed APIs. I've broken things and had to fix them. And I've learned that's okay. It's part of the process.

The most important thing I've learned is to listen to feedback. When people report bugs or suggest features, I try to understand what they're really trying to accomplish. Sometimes the answer isn't adding a new component—it's fixing an existing one or improving the documentation.

The Community

I'm grateful for everyone who's tried Spexop, reported bugs, suggested improvements, or just said "hey, this is cool." Building something in public is weird sometimes, but it's also really rewarding.

I don't have a huge community yet, but the people who do use Spexop seem to genuinely like it. That's enough for me.

What's Next

I'm not entirely sure, to be honest. I'm still actively developing Spexop, adding components, fixing bugs, improving the documentation. There are always things to improve.

I'd like to add more components, refine the API, improve the documentation. Maybe build a visual theme builder (I've started on this, but it's not ready yet). Maybe add React Native support (there's already a basic package, but it needs work).

But mostly, I just want to keep building things that are useful. That's the goal, really. Build useful things, and if other people find them useful too, that's a bonus.

Final Thoughts

Building Spexop has been a journey. It's taken more time than I expected, but I've learned a lot along the way. I've made something I'm proud of, even if it's not perfect.

If you're thinking about building a design system, my advice would be: start small, iterate often, and don't be afraid to change things. Also, document everything. Future you will thank present you.

If you want to check out Spexop, you can find it at spexop.com. The docs are at docs.spexop.com, and the code is on GitHub.

Thanks for reading. If you have questions or feedback, feel free to reach out. I'm always happy to chat about design systems, React, or really anything development-related.

Spexop Design System - Built with TypeScript & React (for now)

WebsiteDocsGitHubnpm

Top comments (0)