A Developer's Guide to the Modern Web Development Landscape

Everything in web development is changing, and for your career as a developer, it's really important that you understand what's going on, what new things to learn, and what not to learn. This article will provide a high-level overview of modern web development with all the things that you need to know right now.

A lot of things have actually changed in the past year or so.

Key Innovations in Web Development

AI Co-pilots

The biggest innovation has been AI co-pilots. These are so good, it has to be said. Just to give an example, here is a new hook called useOptimistic. You can see it knows exactly what is intended here; it can suggest the entire code snippet.

import { useOptimistic } from 'react';

// example optimistic hook
// ...

Now, it might miss a default case here or there, but you can see that's fixed very easily. Thanks to these AI co-pilots, one can forget about a lot of those lower-level details and reason more in a higher-level abstraction about the code. It's a huge change, and it makes it less important to memorize numerous things and algorithms.

TypeScript

Another major change is actually TypeScript. Now, TypeScript has been around for a long time, but in the world of web development, especially React, it has completely broken through in the past year. It has become sort of mandatory, whereas before it was kind of optional. You would see it around, but now it's everywhere and has, in many views, become mandatory to learn if you want to become a full-stack web developer.

Tailwind CSS

Tailwind CSS has also completely taken over. Of course, it's been around for a long time, but now it's also the default in Next.js and is poised to become the default way of styling websites and web apps.

Next.js and the App Router

Another huge innovation, of course, is Next.js. Next.js has released its App Router. Before, they had the Pages Router, but there's lots of innovation here. It's not just Server Components; in fact, Server Actions are arguably the biggest innovation. Yes, there is a bit of a learning curve, but it's the right way forward. It actually makes it a really exciting time to be a web developer because now, with Next.js and all of these tools together, you become very powerful as a developer. It makes it very easy to create full-stack applications.

It's a really exciting time. Yes, it's annoying that as an experienced developer, you have to learn some new things again. Especially TypeScript was kind of annoying to learn; a lot of people went through it last year. It's basically a month or two of struggling, and then you kind of get it. But that's part of the job. The benefit of being a junior or newcomer is that you can go straight to the latest technologies and you can sort of skip ahead. You can leapfrog over the more senior developers that are still kind of stuck with the old technology. That's the one advantage you have as a newcomer.

From Websites to Mobile Apps

Progressive Web Apps (PWAs) haven't really broken through yet. People often prefer to install a native app from the App Store. So how do you convert a website to a mobile app? You could do it yourself, but it can be very painful. Instead, you may want to take a look at various services that make it very easy for you to turn your website into an app. You can connect your URL, change the design, and then publish it to the Android and iOS App Stores.

What You Need to Learn

Traditionally, you would specialize in either front-end or back-end. The view is that over time, it's going to merge together into full-stack web development because a lot of the difficult parts on both sides are being abstracted away. Next.js makes a lot of things easy for you, so over time, as a developer, you're going to work across a wider range of the stack.

Foundational Skills

Regardless of what you're doing in web development, you're going to have to learn the fundamentals. We won't list every little thing you need to know; a lot of those things you will learn as you go.

HTML

For HTML, basically, you have to take a look at semantic tags. Don't just use divs everywhere; try to use a <section> sometimes, or an <article>.

CSS

CSS is really important. Even if you want to learn Tailwind CSS, make sure you master CSS itself first. * The Box Model: Every element on a page, let's say a button, has a so-called Box Model. It has its own size (coming from the text and how big the text is), and then around that, you have padding. Around the padding, you have a border, which may have a certain size and add additional space. Then you have margin, which is essentially space between elements. Every element on a page has this sort of rectangular box. * Layout: To have a nice layout, you want to take a look mostly at Flexbox. You'll want to use Flexbox 99% of the time. Sometimes you want to use Grid, so you should still learn it as well, but Flexbox should be your priority. * Animations and Transitions: When you hover over a button and there's a slight background color that changes, that's a transition. For a fancier effect, like an image loading with a special animation, you would probably do that with an actual animation in CSS. * Media Queries: Make sure your project looks good across a wide variety of devices. We can do that with media queries in CSS.

JavaScript

  • Variables: Of course, you need to know about variables. You want to store some value somewhere in order to work with it. These days, we use let and const. Previously, we used var. People have kind of settled on using const as the default unless you need to reassign a value, in which case you use let. We basically never use var anymore.
  • Arrays: Whenever you have a collection or list of things, you want to put it in an array. These arrays have certain methods. map, for example, is very common in React. forEach lets you go over each one, and push lets you add something. These methods are important to learn.
  • Objects: Whenever you need to represent something in your code, you can have an object. For example, on a real estate website, you may have an apartment. Apartments need to be represented by an object. javascript const apartment = { size: '1200 sq ft', price: 500000, bedrooms: 3 }; We use objects to represent entities in our code.
  • Arrow Functions: In JavaScript, we have Arrow Functions, which are new compared to the traditional function keyword. ```javascript // Traditional function function myFunction() { /* ... */ }

    // Arrow function const myArrowFunction = () => { /* ... */ }; ```

  • Asynchronous Code: Whenever you need to reach across the network to get some data, you may want to use the built-in fetch API. You need to understand how that works. It actually gives you a so-called Promise. You need to learn asynchronous code in general. You don't have to create Promises yourself typically; you only consume them. ```javascript // Consuming a promise with .then() promise.then(value => { /* ... */ });

    // Consuming a promise with async/await async function getValue() { const value = await promise; // ... } `` Typically,async/await` is preferred these days.

  • The DOM: You need to learn about the DOM itself. In the DOM, there are certain events. When you click somewhere, a click event occurs, and you can manipulate the DOM to add elements or change styles. Generally, you need to learn a little bit about the web platform with things like local storage, how URLs work, and how to communicate with a server.

Don't get stuck too long on the fundamentals. It's okay if you don't fully understand some things. At some point, you just have to jump into it and learn a library or framework to really become a useful developer.

Mastering the Frontend with React

Let's say we're going to start off with the front end and learn about React. There are also other options, but React is probably the most popular one. If you want to create a React app, typically these days you're going to use Vite, which is essentially a replacement for Create React App.

  • Components: For React, you need to learn about components. A component is just a JavaScript function, written with a capital case. javascript function PetFormButton({ children }) { return <button>{children}</button>; } Now, whenever you need a button in your project, you can use this component. You don't have to repeat yourself with the markup. But how can you make it different in a certain instance? Let's say you need to change the text. Sometimes it needs to say "Add Pet," and sometimes it needs to say "Save Changes." You can use props to change the component in a particular instance.
  • Hooks: React has so-called hooks. If you have a piece of data and you want to track it over time, you want to use useState. Sometimes you need to go outside your React app, maybe to reach out to a server or local storage. Typically, you want to use useEffect for that.
  • Custom Hooks: Custom hooks sound very fancy, but they are basically just utility functions. Instead of writing your useState and useEffect calls in your component, you can put them away somewhere else, and that's what people will call a custom hook.
  • State Management: If you have a piece of data, you typically start off by just using useState for it. But it's very common that you will need that piece of data in many different components. You can use props to pass that around, but unfortunately, it can make your app too brittle. You'll want to put that piece of state in a dedicated solution. A state management solution sounds very fancy, but you can use the built-in Context API in React, or something like Zustand or Redux. These are typically the most popular options. The Context API and Zustand are getting more popular. Redux is fine to use, and one of its benefits is that it has a more sophisticated dev tool. But purely looking at usage, it does seem that Zustand and the Context API are getting a little bit more popular.

Styling and Best Practices

For styling, the recommendation is to go for Tailwind CSS at this point. And then, of course, you also need to know about common patterns and best practices. You want to make sure that your components, for example, are reusable. There are certain things you can do.

Also, consider things like state in the URL. A piece of data should not always go in useState. Sometimes it's better to make it part of the URL as a search parameter. For example, on a real estate website, if you only want to see houses below a million dollars, you can make that part of the URL. Now the user can bookmark it, come back later, and get the exact same view. They can share it with other people, and they get the exact same view. Some pieces of data should go into the URL, most commonly filter or sorting parameters.

Other Frontend Options

Besides React, which is backed by Meta, there is also Angular (backed by Google), and there's also Vue and Svelte. These are the most common options you have for the front end.

A Note on TypeScript

TypeScript is kind of mandatory. It forces you to be much more precise with your types, which results in much more robust code. But you don't really have to learn it separately. As an app developer, you can just enable it in your React apps, and TypeScript can already do a lot of inference. It can already detect when something is going to be a string, a number, or a boolean. You don't really have to specify that very often yourself. A more advanced concept is generics. In React, you're most commonly going to see that when you create a custom hook.

Embracing Full-Stack Development

The trend is that as a developer, you're going to work along a wider range of the stack. The focus these days should be on becoming a full-stack developer. That means now we also need to take a look at the back end.

Next.js: The Full-Stack React Framework

If we're going to use React, you definitely want to take a look at Next.js. * Routing: Next.js has built-in routing through the file system. Depending on how you structure your folders and files, that's how you do routing. * Server Components & Actions: Next.js these days offers Server Components and Server Actions. A lot of the traditional backend code that you would have in, let's say, a Node.js Express server, is now going to be written in Next.js in your Server Components or Server Actions. Traditionally, if you had a web server, you would have an API endpoint to update some data. You're going to use a Server Action for that now. For getting data, typically you're going to do it in a Server Component. * A Complete Framework: Next.js is a full-stack framework. You don't need a separate back end. You can now create complete websites and web apps with just Next.js, with just the React model, which is very powerful. * Performance: Next.js does a lot of caching for you behind the scenes, which results in performance benefits. Server Components are mostly for performance benefits, and Server Actions are more of a developer benefit. You don't have to create those separate /api endpoints anymore and then hook them up with the front end. You can just create a normal JavaScript function, and it's only going to run on the server. * SSR and SSG: You should also take a look at the more general concepts of SSR (Server-Side Rendering) and SSG (Static Site Generation). They come up quite often and are actually quite similar. SSG basically takes your components and creates HTML out of them during build time. You can put it on a CDN, so when somebody comes to your website, it's very fast. Next.js is really page-focused. It will automatically create HTML out of the whole page with all of the components. SSR is very similar; it also renders things on the server, but it happens at request time. It's more on the fly. Next.js can do that not just for the whole page but for an individual Server Component, independently from the rest of the app. It can render a component by itself on the server and then stream it to the front end. Streaming and Suspense form a very powerful paradigm in Next.js.

Data Handling and Security in Next.js

Patterns and best practices like data fetching have changed. You typically don't use React Query for that anymore; you would do that in a Server Component. When you submit data, you're going to submit it to a Server Action, and you want to make sure that you validate that data with something like Zod. Since Next.js is a full-stack framework and abstracts away the network boundary, it's kind of easy to leak sensitive data, so there are certain ways of avoiding that.

Other Full-Stack Frameworks

Next.js is a React framework backed by Vercel. There are other React frameworks as well. * Remix: Acquired by Shopify, so if you're in the e-commerce space, this is definitely something to take a look at. * Astro: Seems to specialize more in content websites. * Gatsby: Backed by Netlify, but its usage seems to be on a bit of a decline.

Besides React, we also saw that we have Angular, Vue, and Svelte. They all have their own full-stack frameworks as well: Angular Universal, Nuxt for Vue, and SvelteKit.

When to Use a Separate Backend

Does this mean you never need to create a separate backend server anymore? The answer is no; you actually often still need it. For example, for video rendering on the server, that's a very resource-intensive task. It makes sense to spin that out of your main Next.js app into a separate service or backend. Whenever you have some kind of compute-heavy or special task, it makes sense to spin that out. You may also work with a microservices architecture where you have a bunch of separate services.

Here are some common options for separate backend services: * Node.js: The benefit is that you already know JavaScript and TypeScript from the front end. Express and NestJS are common options. Bun is also emerging, but Node.js is here to stay. * PHP: Very popular in the world of WordPress. Laravel is a popular web framework for PHP. * Python: Has become very popular because of data science and AI/machine learning. Django is a popular web framework. * Java: Very popular in enterprise and also used for Android mobile apps. Spring is the web framework there. * Ruby: Has Ruby on Rails. * Go: Is also seen a lot these days.

Understanding Modern Databases

People would traditionally split databases into SQL and NoSQL. The big differences between them have been abstracted away for the most part, mostly through so-called ORMs (Object-Relational Mappers). As a developer, you don't deal directly with your databases; you're going to do it through an ORM like Prisma, Drizzle, or Mongoose. They have abstracted away a lot of the differences. You can just interact with Prisma, and no matter what database you use (whether it's PostgreSQL or MongoDB), the code is essentially going to be the same.

It doesn't make a huge difference which option you go with unless you have some specialized need. SQL-lite is growing very fast because it's probably the easiest one to set up; it's just a file. It does require access to the file system, which can be a problem if you deploy to a serverless platform like Vercel, where you don't get access to the file system.

There are also popular hosted database services like Supabase (PostgreSQL), Firebase, and Vercel, which now also offers a database service.

The Essential Developer Ecosystem

It's also important that you learn the ecosystem. There are many tools around the core that solve specific problems.

  • Shadcn/UI: Has exploded in the past year and has a great shot of becoming a default component library for the web. It's a third-party set of components, but it's different because you don't just npm install it. When you add a component, you get the source code, so you can literally change anything you want. The reason you want to use a third-party library is because it removes a lot of hassle. For example, with a dialog, it handles trapping focus within the dialog, among many other accessibility details. A lot of that work has been done by Radix UI, which Shadcn is built on. Shadcn is basically a Tailwind CSS layer over Radix UI.
  • Zod: We talked about validating data on the server side. You don't know what you're going to get from the front end, so you want to validate that what you get is of the shape you expect. You can do that with Zod. The cool thing is you can also do it on the front end with your forms.
  • React Hook Form: You may want to use React Hook Form to control your forms. It makes it very easy to deal with loading and error states. You can connect Zod to your forms for validation. The combination is very powerful, and you can even use Shadcn because it also has components for forms.
  • Framer Motion: Very popular for animations. Instead of using plain CSS animations, you may decide to use Framer Motion for pretty much any animation.
  • Authentication: There is an open-source solution called NextAuth.js. Some people are a little bit frustrated with it because the docs and developer experience could be improved. You may also want to take a look at third-party options for authentication, which can be easier to get started with.
  • Payments: Stripe is pretty much the most popular option. Some authentication providers are also coming out with payment solutions, which is powerful because payment is often closely related to user management, roles, and permissions.
  • Hosting Providers: For React and Next.js, Vercel is a popular option because they back Next.js. Netlify is another option. In general, Vercel seems to be getting more and more popular.
  • Git and GitHub: Git is for managing your codebase, and GitHub is a place to host your Git repository. There's also GitLab and other options.
  • Mobile Apps: As mentioned, there are services to convert websites to apps. If you want to do it completely yourself, there is innovation happening with React Native and Expo that you may want to take a look at.

This is a lot to learn, but you just have to take it one day at a time, and you'll see that in a couple of months, you can get pretty far.

This article should give you a good high-level overview of where we are currently at in web development. It's a really exciting time. There's lots of innovation and many things are changing, but if you keep up, things are only getting better.