Why I still write code in a customer-facing job
6 min read
Updated October 27, 2026
When a customer tells me something is broken, the first thing I want to do is break it myself. A problem I can reproduce is a problem I can explain, to the customer and to the engineers who will fix it, and explaining is most of what a customer-facing job at a developer platform comes down to.
I was a frontend engineer before I joined Vercel in 2021 as its first Japanese-speaking customer success hire, and I now lead customer success for Asia Pacific and Japan. Each step moved the job further from code. I still write it, and I think anyone in customer success or solutions at a technical company should.
Reproduce the issue yourself
A ticket that says “the page shows old data in production” can mean a dozen things. A repository where the bug happens after next build && next start and not in next dev means one or two. The second is worth far more to an engineer, and building it is within reach of anyone who can run a starter project.
What I collect before I escalate anything:
- Versions.
npx next infoprints the Next.js, React and Node.js versions and the OS in one go. Paste it as is. - Where it happens. Local dev, a local production build, a preview deployment or production. A lot of “platform bugs” are differences between dev and a production build, especially around caching.
- The smallest code that shows it. A fresh starter with only the failing piece added. If it doesn’t fail in the starter, the difference between the starter and the customer’s app is your answer.
- Expected and actual. One sentence each, with a URL and a timestamp that includes the time zone. When your teams are spread from Osaka to San Francisco, “this morning” means nothing.
Read configs and logs before code
Much of what gets reported as a bug turns out to be configuration. Before anyone opens the source, read what the system already tells you.
- Config.
next.config.ts, environment variables per environment, redirects and rewrites. Put preview and production side by side. - Build output. Next.js lists every route with a symbol: ○ for static, ƒ for dynamic. If the page the customer expects to be fresh is marked ○, you’ve found the stale-data bug without reading a line of their code.
- Runtime logs. Status codes, which function ran, how long it took. A 504 that always arrives after the same number of seconds is usually a function timeout.
Then the response headers. One command shows whether a page came from the cache:
curl -sI https://example.com/pricing | grep -iE "^(cache-control|age|x-vercel-cache):"
x-vercel-cache: HIT with a large age means the page is being served from the cache, and cache-control says how long it may stay there. Other hosts use different header names; the idea is the same.
Build demos with v0
v0 is Vercel’s AI tool for generating React and Next.js interfaces from a prompt, and I’ve presented it at events in Japan, including a webinar on AI and yōken teigi (要件定義, requirements definition, the phase where a Japanese project writes down what it’s going to build).
In a customer conversation, a working screen does more than a slide. A rough version of what they described, in Japanese, with the kind of data they actually have, turns a vague discussion into a specific one. People point at the screen and say “not like that”, and that’s the requirements conversation happening faster.
One rule: a demo is a sketch, so say it out loud every time. Otherwise the customer will reasonably assume the hard parts (authentication, real data, permissions, their security review) are as finished as the buttons look.
Know Next.js well enough to have an opinion
Customers ask things like “should this page be static or dynamic?”, “where should we fetch this data?” or “is it worth migrating to the App Router now?” If every answer is “let me check with engineering”, you’re a mail forwarder, and the customer will start going around you.
You don’t need to be the expert. You need an opinion, the reasons behind it, and an honest sense of how sure you are: “I’d make this page static and revalidate it, because it changes once a day. If it has to be different per user, that changes things, and I’ll confirm with our engineers.” That answer is useful even when it needs correcting later.
The cheapest way to keep an opinion current is to own a real project on the same stack. This site runs on Next.js and I maintain it myself, with Claude Code. Upgrade problems should happen on your own project before they happen in front of a customer.
Earn engineers’ trust
Every escalation costs an engineer a context switch, and the customer-facing people they trust are the ones whose tickets arrive half-debugged. Say what you’ve already ruled out, so nobody repeats it. Separate what you know from what you suspect: “reproduced on one version, not on the previous one” is a fact, “probably a regression” is a guess, and the ticket should label which is which. Don’t escalate the same issue through two channels, and read the linked issue or pull request before asking for a status update. When it’s fixed, tell the engineer what it meant for the customer.
A template helps:
Summary: <one sentence>
Impact: <who is affected, since when, with time zone>
Env: <output of npx next info>
Where: local dev / local build / preview / production
Repro: <link to a minimal repository>
Expected: <one line>
Actual: <one line>
Ruled out: <what you already checked>
Ask: <the exact question you need answered>
Know when to hand off
Being technical doesn’t mean keeping everything. Hand it to engineering when any of these is true:
- Your reproduction points at the framework or the platform itself. Engineering needs it now; another afternoon of poking at it only delays the fix.
- It involves security, data loss or an outage. Those have their own process; follow it.
- The customer is about to make an architecture decision based on your answer, and you wouldn’t bet on that answer.
- You’ve spent an hour without narrowing it down.
And don’t fix a customer’s production code for them. Point to the line and write the example; the commit should be theirs, because they’ll maintain it. Being technical is what makes the handoff faster and cleaner.
Keep what you build
Three habits that add up over a year. Turn every interesting customer issue into a minimal repository and keep it; you end up with your own library of known problems. Read the release notes of the product you support, every release, and try the one change customers will ask about. And if you use an AI coding tool, read every diff: Claude Code is my daily driver, and it only makes me faster because I check what it wrote.
What you build matters more than perfect English
In November 2024 I gave a keynote at Qiita Conference 2024 Autumn with Shusaku Uesugi, an engineer at Vercel, about how two people with unconventional careers ended up at a global startup. The message I care most about: what you want to build matters more than perfect English, and a career that didn’t follow the standard path is an asset. (It’s listed on the speaking page, and the longer version of my own path is in From translator to frontend engineer.)
If you work in Japan, you may worry more about your English than about your technical depth. I’d flip that. A minimal reproduction, a log excerpt and a curl output read the same in Tokyo and San Francisco. Short English with a clear reproduction gets an engineer on the other side of the world what they need; a long, polished paragraph without one usually doesn’t.
As for unconventional careers: someone who worked in support, marketing or translation and then learned to code can follow both the customer’s problem and the engineer’s. That’s rarer than a clean CV.