Ben Shumaker, February 10, 2025
Back in January, I made this startup's first landing page. I used Cursor to make an interactive background (like the one on this page). Within a couple days of publishing, multiple developers messaged me compliments. One even asked if I hired a professional designer.
I was surprised by the feedback, because it was super easy to make. I basically just prompted and reprompted LLMs. Artistic components are perfect for AI: they're isolated, they can't cause serious damage, and you can verify the logic by looking at the result. Here's the React + Tailwind code, simplified a bit.
import { useState } from 'react'
const COLORS = ['#FFD980', '#FF8480', '#81FF80', '#80EAFF']
export default function Background() {
return (
<div
className="absolute top-0 left-0 w-full h-full grid bg-[#050505]"
style={{
gridTemplateColumns: 'repeat(auto-fill, 32px)',
gridTemplateRows: 'repeat(auto-fill, 32px)',
}}
>
{[...Array(3000)].map((_, i) => (
<Cell key={i} />
))}
</div>
)
}
function Cell() {
const [tempActive, setTempActive] = useState(false)
const color = COLORS[Math.floor(Math.random() * COLORS.length)]
return (
<div
onMouseEnter={() => {
setTempActive(true)
setTimeout(() => setTempActive(false), 1000)
}}
className="w-8 h-8 border"
style={{
background: tempActive ? `${color}1a` : '#050505',
border: `solid ${tempActive ? `1px ${color}` : '0.5px #20202099'}`,
}}
/>
)
}
I suspect many developers make landing pages like phpMyAdmin because it's easy. Polished aesthetics take hard work, design taste, and non-IDE tools like Figma. That's still true for top-tier designs, but now I think you can get noticeably further with minimal effort, just using your IDE.
I thought I'd share some examples. They each only took a couple prompts.
There's a ton of fancy tricks with css backgrounds. They used to require sleuthing Stack Overflow and creativity. But LLMs know all the tricks.
A lot of saas companies add gridlines that fade-out along the edges (like Browserbase). It's looks really nice. And once you know how, it's less than 20 lines.
export default function Background2() {
return (
<div
className="absolute top-0 left-0 w-full h-full bg-[#050505]"
style={{
backgroundImage: `
radial-gradient(closest-side, transparent, #050505),
linear-gradient(to right, #ffffff50 1px, transparent 1px),
linear-gradient(to bottom, #ffffff50 1px, transparent 1px)
`,
backgroundSize: 'cover, 50px 50px, 50px 50px',
backgroundRepeat: 'no-repeat, repeat, repeat',
transform: 'scale(2) rotateX(60deg) rotateZ(20deg)',
}}
/>
)
}
I think one of the coolest gains from LLMs is how good they are at writing special syntaxes like regex, css, and sql. I can write them myself, but it sucks.
Here's another common effect. A grid of dots, with a subtle fade from top to bottom.
export default function Background3() {
return (
<div
className="absolute top-0 left-0 w-full h-full bg-[#050505]"
style={{
backgroundImage: `
linear-gradient(
to bottom,
#050505,
transparent 40%,
transparent 60%,
#050505
),
radial-gradient(circle at center, #ffffff50 1px, transparent 1px)
`,
backgroundSize: '100% 100%, 50px 50px',
}}
/>
)
}
And it's not just backgrounds. It easily extends to using multiple components in creative ways.
Here I tried making a background like the gridlines on Stripe's landing page.
export default function Background4() {
const rows = 4
const cols = 5
return (
<div className="absolute inset-0 bg-[#0a0a0a] overflow-hidden">
<div className="w-full h-full relative">
{[...Array(rows)].map((_, i) => (
<hr
key={i}
className="absolute left-0 w-full h-[1px] border-none"
style={{
top: `${(100 * (i + 1)) / (rows + 1)}%`,
background: `repeating-linear-gradient(
to right,
#2a2a2a 0,
#2a2a2a 8px,
transparent 8px,
transparent 16px
)`,
}}
/>
))}
{[...Array(cols)].map((_, i) => (
<hr
key={i}
className="absolute top-0 w-[1px] h-full border-none"
style={{
left: `${(100 * (i + 1)) / (cols + 1)}%`,
background: `repeating-linear-gradient(
to bottom,
#2a2a2a 0,
#2a2a2a 8px,
transparent 8px,
transparent 16px
)`,
}}
/>
))}
</div>
</div>
)
}
LLMs even have reasonable accuracy at one-shotting animations with simple movement patterns and useStates.
Here's an example of a starry background. Turns out stars are super easy. Though be careful with movement, it's easy to overdo it.
"use client";
import { useEffect, useState } from "react";
export default function Background5() {
// Use client-side only rendering
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
// Don't render anything during SSR
if (!mounted) {
return <div className="absolute top-0 left-0 w-full h-full bg-[#050505]" />;
}
return (
<div className="absolute top-0 left-0 w-full h-full bg-[#050505]">
{[...Array(300)].map((_, i) => (
<Star key={i} />
))}
</div>
);
}
function Star() {
const [time, setTime] = useState(Math.random() * 2 * Math.PI);
const { top, left, opacity, size } = useState(() => ({
top: `${Math.random() * 100}%`,
left: `${Math.random() * 100}%`,
opacity: Math.random() * 0.3 + 0.3,
size: Math.random() < 0.3 ? 2 : 1,
}))[0];
useEffect(() => {
const animate = () => {
setTime((t) => t + 0.01);
requestAnimationFrame(animate);
};
requestAnimationFrame(animate);
}, []);
return (
<div
className="absolute bg-white rounded-full"
style={{
top,
left,
opacity,
width: size,
height: size,
transform: `translate(
${Math.sin(time) * 5}px,
${Math.cos(time) * 5}px
)`,
}}
/>
);
}
I don't think LLMs are replacing designers anytime soon. All the hardest parts of design are still hard: understanding users, deciding which features should exist, creating a unique aesthetics...
Still, as a design-engineer, I've been consistently impressed with LLMs' ability to rip-off standalone components. And I've been having fun making interactive designs.
I think our homepage seems cool because it's unique. Dynamic designs are so rare. Design tools like Figma are horrible for anything with state. Trying to "no-code your way to success" quickly becomes harder than just coding.
So in a way, designing in code is more powerful. You can make things that are alive. And because nobody else does it, it often feels cooler than static designs.