
Front-end Development & Prototyping
Learn how I bridge the gaps between product, design, and engineering teams.
Should designers learn to code?
Yes! Thanks for reading.
const skills = [
"storytelling",
"design",
"illustration",
"motion graphics",
"code",
];
if (skills.includes("code")) {
// Todo: Create Function
console.log("Let's go!");
}
But seriously, being able to work across the disciplines and contribute to the products we design is incredibly rewarding. Don’t missunderstand, I’m not a “full stack” guy but I know enough about the development, front and back, to be supportive in most engineering conversations - and isn’t that what it’s all about? Supporting our teams.
As the industry has evolved, so have I. I have learned a lot of languages, frameworks, and build systems. Here are a few: HTML, CSS, Javascript, Ruby, Python, PHP, C#, ClojureScript, Webpack, Vite, React, Vue, Angular, Style Dictionary, Tailwind,, and so many others.
Developing Imagination
Today, I find myself using React, Vite, and Tailwind when I want to quickly prototype something. This combo is a great way to showcase simple ideas, communicate interactions, and create an artifact that could eventually become production code. I dive a bit deeper on this topic here.
Checkout my current starter project, react-vite-template, if you’re interested.
A Quick Overview

This project needed to support a number of qualities:
- React/Typescript was a the language of choice
- Customizations had to be simple
- Prototyping had to be fast
- It needed to be deployable, destroyable, and password protected
What’s in it?
- Typescript
- Vite
- CSS Modules
- Phosphor React
- Tailwind 4
- AO Design Tokens
- Ant Design 5
I used a custom component called AuthenticationWrapper
to check for a session when certain pages were requested.
const AuthenticationWrapper = (props: any) => {
const [isAuthenticated, setIsAuthenticated] = React.useState(false);
const [inputPassword, setInputPassword] = React.useState("");
useEffect(() => {
const storedAuth = sessionStorage.getItem(SESSION_KEY);
if (storedAuth === password) {
setIsAuthenticated(true);
}
}, []);
const handleSubmit = (e: any) => {
// handle login
};
// Continue if authenticated or login
if (isAuthenticated) {
return <AppProvider>{props.children}</AppProvider>;
} else {
return (
<Login
loginCallback={handleSubmit}
setInputPassword={setInputPassword}
inputPassword={inputPassword}
/>
);
}
};
Additionally, I used the React useContext
hook to share global state across my routes.
// AppContext.tsx
export const AppProvider = ({ children }: { children: React.ReactNode }) => {
const [count, setCount] = useState(0);
const incrementCount = () => {
setCount((prevCount) => prevCount + 1);
};
const value = useMemo(() => ({ count, incrementCount }), [count]);
return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
};
// App.tsx
import { useContext, useEffect } from "react";
import { AppProvider, AppContext } from "./AppContext";
const Action = ({ count, incrementCount }: any) => {
return (
<div className="flex gap-4 items-center">
<Button
size="large"
type="primary"
onClick={() => {
incrementCount();
console.log({ count });
}}
>
Increment Count
</Button>
<code>{JSON.stringify({ count })}</code>
</div>
);
};
Once I had the all necessary elements, I had to ensure that I could deploy it. Vercel has been a faily reliable platform for hosting projects like these. Again, if you’re interested in these details, check out my starter template, react-vite-template, on Github.