Design Engineer Application
Subhaprada Chand — Unkey
I have spent around 5 days on this application. Started by running the full dev stack, creating real APIs and keys, and understanding the product as a developer would. Then focused on redesigning the parts that needed it.
Before this, I built Nurturli from scratch — design, code, user research, shipping. I work in code, iterate in the browser, and reach for Figma when the team needs alignment.
I picked two surfaces that shape first impressions — the marketing site and the Create New Key flow in the dashboard.
On the marketing side, I focused on the hero and the navigation. I redesigned the hero layout, introduced Clash Display typography, built a cyan accent system, and simplified the nav from 7 competing links to a focused hierarchy with a Product dropdown.
In the dashboard, I rethought the key creation experience. Added a live SDK code preview that updates as you fill the form, improved inactive field guidance so disabled fields point you to the right toggle, and brought visual consistency between the marketing site and the product.
Every choice is documented — what was tried, what was rejected, and why. Click any card to see the full breakdown with before/after screenshots.
Unkey SDK Code Preview
Two SDK code touchpoints — on the empty API page and inside the Create Key modal — that tell developers 'you're ready to integrate' instead of leaving them guessing.
Inactive Section Feedback
Toggle-gated sections in the Create Key form looked the same whether on or off. Clicking a disabled field did nothing. The fix guides your eye straight to the controlling toggle with an animated border glow.
Code Panel Feedback
The live code preview updates as you fill the form, but only the first few lines are visible due to its position in the layout. Added small visual signals so users know the code is keeping up — and are reminded they can use it directly instead of going through the form every time.
Hero Layout — Split Composition
Redesigned the homepage hero from a centered layout to a split composition, giving both the text and the circuit board SVG room to breathe.
Hero Copy: Finding the Right Headline
This is the most opinionated change I made. I believe a design engineer's role at a small team like Unkey extends to copy — if a user reads it, it's design. The existing headline is a conscious platform play, broad by design. I went through several iterations, first toward feature specificity, then realised that approach excluded too much of what Unkey does. The final headline tries to hold both: clear enough to self-qualify, broad enough to cover the full product.
Typography — Clash Display
Introduced Clash Display as the display typeface for headlines, adding a visual layer that's more in tune with the circuit-board aesthetic and distinct from the body text.
Accent Color — Reflected Light
Introduced cyan as an accent color that behaves like reflected light rather than flat paint.
Navigation: Hierarchy, Product Visibility, and Use Cases
Evolved the nav from a flat list of 7 links to a focused hierarchy with a Product dropdown, a Use Cases dropdown, a live Status indicator, and a cleaner primary rail.
I design in code.
Code is the output anyway, so that's where I design. With AI-assisted tools, iteration at the code level is fast enough that going back to Figma is rarely necessary. I get a design vision into the browser, use the actual design, play around with it, and iterate directly in code. This also cuts down on any handoffs or translations between design and code. What is being designed is what ships.
I use tools like Storybook to design.
I build new components and design languages in isolation. It's where I define how something looks and behaves before it touches the rest of the app. It gives me a focused space to explore states, variants, and interactions without the noise of a full page around it.
I write down what didn't work.
Not as a formality. I genuinely find it useful to come back to "why did we reject this?" three weeks later. This whole application is built on that habit.
Design is everything a user touches.
Copy, error messages, empty states, loading sequences — if a user reads it, clicks it, or waits for it, it's design. The hero headline change is a design decision, not a marketing one. At a small team like Unkey, a design engineer who only touches visuals is leaving half the experience unowned.
I care about how it feels and works, not just how it looks.
The interaction layer is part of the design. The toggle glow, the code preview updating as you type, the disabled cursor pointing you to the right control. These aren't polish added at the end. They're design decisions made during the build. How something responds to you matters as much as how it looks.
Spending time inside the Create Key flow gave me a close look at how keys get configured — through the dashboard and through the SDK. A few things stood out that felt like product gaps rather than design ones.
API Key Templates
Every key creation requires the full configuration to be specified from scratch: prefix, credits, rate limits, permissions, expiration. For a SaaS running multiple pricing tiers, this means repeating the same config in every createKey call, or building a template layer on top of Unkey yourself.
I know this isn't just a design change. It touches the data model, the API (templateId as a parameter in createKey), and the dashboard. But I think it's worth raising. The value is concrete: consistency across keys, simpler plan management when a user upgrades, and a reduced API surface for common patterns.
Before
await unkey.keys.create({
apiId: "api_xxx",
name: "alice",
externalId: "user_123",
prefix: "sk_live",
byteLength: 16,
ratelimit: {
type: "fast",
limit: 100,
refillRate: 100,
refillInterval: 60000,
},
remaining: 1000,
refill: {
interval: "monthly",
amount: 1000,
},
permissions: ["read", "write"],
expires: Date.now() + 30 * 24 * 60 * 60 * 1000,
});After
await unkey.keys.create({
apiId: "api_xxx",
templateId: "tmpl_pro_tier",
name: "alice",
externalId: "user_123",
});A pragmatic starting point before committing to full templates: extend the existing keyspace defaults — currently just prefix and byte length — to cover credits, rate limits, and permissions. No new entities, no API changes. Just make the Settings page more complete and have the API respect those defaults when fields are omitted. Proves the concept with minimal investment.