Start with the Senior Frontend Developer. This is part 1 of 3 in the Essential Skills series (4 posts in total). Also in this series: Senior Frontend Developer, Frontend Team Leader, When Generation Is Cheap.
The senior frontend map is the baseline. You still need that list. This post is the rest of the slice: the names you will meet on the other side of the contract, and what changes when you own both sides of a bug at 2 a.m.
I am a frontend-shaped senior who has crossed that line more than once. Years ago that looked like leaving a Laravel API and an AngularJS client for Spring Boot and Angular. The useful lesson was not “learn Java.” It was how much of the job lives in the seam.
Roadmap.sh/full-stack will give you more bubbles than you can color in. Use it as a dictionary. Do not use it as a mandate to become a specialist in every box.
“Full-stack” is a title teams hand out for two different jobs. One is a specialist in two places. The other is a senior who can take a slice of product from the UI through the data and back, and who knows where their depth ends. This post is the second job. If you need the first, you are hiring two people.
How to read this
Same altitudes as the frontend post:
- Junior. You can add a field to an existing endpoint and show it on a screen, with help.
- Mid. You can take a feature through handler, table, and UI without being walked through each layer.
- Senior. You own the contract between the layers — identity, empty, failure, cache, authz — and you know when the slice has left your depth.
The frontend skills do not get a second copy here. Go back to part one for language, CSS, framework, and testing on the client.
The boundary is the job
A mid full-stack developer writes a handler, a table, and a screen. A senior owns the answers both sides will live with:
- What is the identity of this thing, and who is allowed to mint it?
- What does empty mean — never existed, deleted, or not visible to you?
- What does a partial failure look like? Did the write happen?
- Which errors are safe to show, and which are a leak?
- What did we cache, and whose truth did we just freeze?
Pagination, idempotency, validation, and authorization are not backend trivia. They are the product. Get them wrong and the UI becomes a set of apologies.
Backend languages and frameworks
You need one server-side language well enough to ship and read production code in it. The name matters less than whether you can follow a request from the route to the query and say what it costs.
What you will meet:
- Node.js — Express, Fastify, NestJS, the occasional Hono or raw
node:http. Same language as the client; the trap is pretending that makes it the same job. - Java / Kotlin — Spring Boot (Web, Security, Data), sometimes Quarkus or Micronaut. Common next to Angular in enterprise. I have lived this migration.
- Python — Django, FastAPI, Flask. You will meet it in data-heavy and internal tools.
- C# — ASP.NET Core. Same role as Spring in a lot of shops.
- Go — small services, CLIs, the thing the platform team already wrote.
- Ruby / PHP / Laravel — still everywhere. You should be able to read them. You do not have to start a new one.
What senior looks like. You can sit with a backend specialist and change the interface before it ships, without wasting their time or pretending you own the query planner. You can add an endpoint, a migration, and a test in the team’s stack. You cannot, and should not, claim specialist depth in all of the above. Pretending you can is how fullstack becomes a lie.
Data
What you will meet:
- Relational: PostgreSQL is the default I want. MySQL / MariaDB is the default a lot of companies already have. SQL Server in Microsoft shops.
- You need: schema design, primary and foreign keys, indexes you can justify, transactions, isolation enough to be dangerous,
EXPLAINon the query you are afraid of, migrations (Flyway, Liquibase, Alembic, Prisma Migrate, Django migrations, Knex). - Document / custom: MongoDB, DynamoDB, Firestore. Use them when the access pattern is a document, not because you did not want to learn joins.
- Cache: Redis (or the managed equivalent) for sessions, rate limits, and the thing you should have been able to recompute.
- Search: Elasticsearch / OpenSearch, Postgres
tsvector, or a hosted search. Not every “we need search” is Elastic. - Access layers: Prisma, TypeORM, SQLAlchemy, jOOQ, Entity Framework, raw SQL. An ORM is a tool. It is not a substitute for knowing what SQL it emits.
What senior looks like. You can design a schema you will not have to apologize for in a year. You know when a document store is a fit versus a habit. You treat migrations and backups as product work. Listing PostgreSQL and MongoDB on a resume is not a skill.
APIs
What you will meet:
- REST / HTTP JSON — the default. Resources, verbs, status codes, problem+json or a team error envelope, pagination (
cursorversusoffset), filtering, idempotency keys on anything a client might retry. - GraphQL — schema, queries, mutations, dataloaders, persisted queries. Use it when over-fetching was real. Apollo, Yoga, Hasura, .NET Hot Chocolate.
- RPC-shaped: gRPC (especially service-to-service), tRPC on TypeScript-only teams.
- Contracts: OpenAPI / Swagger, protobuf, GraphQL schema as the source of truth. Codegen (Orval, openapi-generator, graphql-codegen) so the client is not typing the same shape by hand.
- Realtime: WebSockets, SSE, a message you should have made a poll. Socket.IO still appears.
What senior looks like. You build APIs that are boring to use. Stable errors, an explicit version or an explicit choice not to version, pagination that does not lie. GraphQL is not a personality and it is not required. The senior move is choosing the shape the UI can be honest about.
Authn, authz, and the things the UI cannot be trusted with
What you will meet:
- Authentication: sessions and cookies, JWT access tokens, refresh rotation, OIDC / OAuth 2.0 (Auth0, Keycloak, Entra ID, Cognito, a company IdP). Passkeys and WebAuthn on newer products.
- Where it lives: HttpOnly cookies plus a BFF, versus tokens in JS. I have a longer take on auth patterns for Angular.
- Authorization: roles versus permissions versus relations (the Google Zanzibar / OpenFGA conversation). Row-level rules. The check happens on the server. The UI hiding a button is UX.
- Secrets: env files, a vault (Doppler, Infisical, AWS Secrets Manager, Kubernetes secrets), rotation. Never in the SPA bundle.
What senior looks like. You can draw the flows and say which part is identity, which part is permission, and which part is a client convenience. If the client hides a button and the server trusts that, you have a demo.
Failure, jobs, and the seam
The bugs that make fullstack worth having only exist because both sides are slightly lying.
What you will meet:
- Retries, timeouts, cancellation, idempotency.
- Background work: a queue (SQS, RabbitMQ, Redis lists, Postgres-backed jobs), a scheduler (cron, Cloud Scheduler, Hangfire), an outbox if you cannot lose the write.
- Caches that disagree with the database. CDNs that disagree with both.
- Distributed traces and correlation IDs so “the network tab shows 500” is the start, not the end. OpenTelemetry is the name I want; Zipkin / Jaeger / Datadog APM are what you will actually open.
Stories you should be able to reconstruct: the user double-submitted; the job ran twice; the cache still has the old name; the client retried a POST; the session expired mid-wizard; the list and the detail disagree about whether the record exists.
What senior looks like. You know which log is the truth, which metric would have caught it, and whether the fix is a unique constraint, an idempotency key, a clearer error, or a UI that stops offering an impossible action.
Testing the slice
What you will meet:
- Unit tests on the server: Jest / Vitest, JUnit, pytest, xUnit — match the language.
- Integration tests against a real database (Testcontainers is the habit I want) rather than a mock that cannot fail the way production fails.
- Contract tests if two teams own the seam (Pact, or a shared OpenAPI fixture).
- The frontend suite from part one still applies to your UI.
What senior looks like. You test the contract, not only the handler and not only the button. A mock that cannot express “unique violation” will not save you.
Delivery, cloud, and ops
CI, a host, and a way to see production errors are part of owning the slice. “We run Kubernetes” is a landscape, not a personality.
What you will meet:
- CI/CD: GitHub Actions, GitLab CI, Jenkins, Azure Pipelines. Build both sides, run migrations as an explicit step, deploy without folklore.
- Cloud: AWS (the one you will meet most: ECS/Fargate or EKS, RDS, S3, CloudFront, IAM). Azure and GCP in companies that already chose them. A PaaS (Fly, Render, Railway, Heroku-shaped) on smaller products.
- Runtime: a process you can restart, a container (
Dockerfile, compose), a function (Lambda, Cloud Functions) if the slice is that shape. Kubernetes enough to read a Deployment and a Service — not enough to be the cluster person. - Edge and static: the frontend still ships through a CDN. Preview environments. The build is privileged.
- Observability: structured logs, metrics (Prometheus / Grafana or the cloud equivalent), errors (Sentry), uptime. Health checks that mean something.
What senior looks like. You can ship the slice and own the failure after the container starts. You treat backups and migrations as yours. You do not need to be the platform team. If your idea of fullstack DevOps is “I can write a Dockerfile,” you have a starting point, not the skill.
Security and privacy beyond the SPA
What you will meet:
- OWASP API Top 10 as a reading list, not a poster: injection, broken authz, mass assignment, SSRF in the things you fetch server-side.
- Encryption in transit (TLS everywhere) and at rest (the database and the bucket). You do not invent crypto.
- PII: what you log, what you retain, GDPR / CCPA as constraints on the model, not only on the marketing site.
- Supply chain: lockfiles, image scanning, the same install-hook problem as the frontend.
What senior looks like. You know when the slice has left your depth and a specialist should read it. You have made the seam clear enough that they can start.
Soft skills on this side of the stack
The frontend list still applies. Two extras show up the moment you own the slice:
- You translate for people who only see one side — “the API is fine” is not a diagnosis.
- You estimate work that includes migration risk, not only component hours.
- You know when to call a backend specialist, a DBA, or security instead of coloring in another bubble.
What this title is not
It is not a mandate to learn every cloud service and a machine-learning library so the roadmap looks complete. TensorFlow, PyTorch, and “we should add AI” are not essential full-stack skills. (How generation changed the craft bar is the last part of this series.)
It is also not a substitute for specialists. A serious data problem, a serious security review, a serious traffic shape — those are people you bring in. The fullstack senior’s job is to know when, and to have made the seam clear.
Where this post stops
Own the contract, the failure that crosses it, and enough of the other side to change the interface on purpose. The names above are the landscape. The altitude is still ownership.
The frontend post is the craft bar for the UI. If the job became other people’s work more than your own, that is the team lead post.