What
could we learn from entry-level students in front-end web development?
As seasoned professionals, you might think you’ve seen it all, but the
truth is that the newcomers are asking the most intriguing questions and
making connections that those of us who have spent years on the front
end may have never considered.
I felt uninspired for a
spell in 2019 and decided to enroll in a beginning-level community
college course on web development as a way to “spice” things up, sort of
like going backwards in order to move forwards. I had no interest in
being an old dog learning new tricks; what I wanted was to look at
front-end development through the eyes of a beginner in 2019 after
having been a beginner in 2003.
Fast-forward five years, and I’m
now teaching that class for the same college, as well as three others.
What I gained by reprising my student status is an obsession with
“a-ha!” moments. It’s the look in a student’s eyes when something
“clicks” and new knowledge is developed. With the barrier to learning web development seemingly getting higher all the time, here I am, making merry with the basics. (That linked post to Rachel’s blog is what spurred me to go back to school.)
With
several years of teaching under my belt, I have plenty of opinions
about the learning landscape for web development. But what I am more
interested in continues to be vicarious living through the eyes of my
entry-level students and the consistent sparks of knowledge they make.
Questions
are often the precursor to an “a-ha!” moment. And my students ask some
pretty darn interesting questions every term, without fail, questions
that have forced me to reconsider not only how I approach curriculum and
instruction but also how other people think about The Web™ as a whole.
I’ve
made a practice of collecting handfuls of student questions and
comments. That way, I can reflect on how I might respond or answer them
for future students and reference them as I write and update my lesson
plans. I thought I’d share a few of them because, I hope, it will give
you an idea of what those getting into the field are curious about. I
think you’ll find that as many of us debate and decry the value of
JavaScript frameworks, Core Web Vitals, AI, and whether Typescript is a
necessary evil, the people cracking into web development are
asking the most interesting questions in the field and are making way
different connections than those of us who have spent forever on the front end.
These
are pulled straight from students in the current Spring term. We’re
only three weeks into the semester, but check out what sorts of things
are already swirling around their minds as we discuss semantics,
accessibility, and writing modes.
“I really never thought
of this; however, code could be inclusive, and how coding could express
empathy. While reading this portion of the context, I was thinking
about my Kindle and how the Kindle can have audio, change my font style,
larger/smaller font, and lighting. All of this helps me to read and
navigate my books better depending on my surroundings and how much
accessibility I will need. For example, when I am driving, I love my
audiobooks, and at night, I use my dim setting and change font size
because it’s the end of the day, and my eyes don’t want to do too much
work reading smaller text. It’s really fascinating that coding can do
all of this.”
“If we are confused about our
coding and it doesn’t make sense to us, it will definitely confuse the
readers, which is the opposite of our end goal, accessibility. There are
also times when we might want to use <div> where we could use <article> or <nav>
or any of the other important elements. It’s essential to fully
understand the elements and their uses in order to write the cleanest
code.”
“Tackling CSS logical properties this
week felt like a juggling act, trying to keep all those new concepts in
the air. Swapping left and right for inline-start and inline-end is a
bit confusing, but it’s cool to see how it makes websites more welcoming
for different languages.”
“What are the legal
implications of website liability? I couldn’t imagine the size of a
class action lawsuit that Facebook would get smacked with if a rogue
developer decided to pin a gif of a strobe light to the top of the
world’s newsfeeds. Are websites subject to the same legislation that
requires buildings to have wheelchair ramps?”
“Sometimes,
I wonder how to make all this new stuff work on old browsers that might
not get what I’m trying to do. I also get stuck when my page looks
great in one language but breaks in another. What’s the best way to
check my work in different languages or writing modes?”
“One
of the big things that really got me stoked was learning how to make
content in Flexbox the same size using flex or flex-basis. This was a
really big thing for me last semester when I was working on my final
project. I spent a lot of time trying to figure out how to make the
content in Webflow equal in size.”
“Hearing the
terms “Writing Modes” and “Logical Properties” in CSS was a bit of a
concern at the beginning of this week. A lot of CSS I remember was
beginning to come back, but these two were new. After going over the
course modules, my concern lifted a lot, mainly because Writing Modes
were the layout of text in a certain element. As simple as I thought it
was, it was also very important considering how writing modes change in
different countries. Learning how these writing modes change the flow of
text showed how much more inclusion you could bring to a website,
allowing for different languages to be filtered in.”
“Although
in the previous course, we learned how flexbox and grid can be used to
style interesting content on sites, we didn’t study how they were made
with CSS. It was surprisingly simple to grasp the basic concepts of
setting up a flexbox or grid and how their children can be positioned on
a main axis and cross axis. I especially enjoyed setting up grids, as
both methods are intuitive, and the concept of selecting the grid lines
that an element sits in reminds me of how some programming languages
implement arrays and ranges. Python, for instance, allows the user to
select the last element of an array using -1 just as the grid-column: 1/-1; the property can specify that an element spans until the end of a row.”
“Logical
Properties were intimidating at first, but it was just changing the
code to make it make sense in a way. After learning CSS — a bit a while
ago — Logical Properties seemed more modern, and I think I adapted to it
quickly.”
“But as a whole, I could see the
building of websites to be a very easy thing to automate, especially in
this day and age. Perhaps that is why site builders do not get super
specific with their semantics — I usually only find <html>, <body>, and <head>, while the rest is filled with <div>.
Especially when it comes to companies that push a lot of articles or
pages out onto the internet, I can see how they would not care much for
being all-inclusive, as it matters more that they get the content out
quickly.”
“I did not think I would enjoy coding,
but so far, I like this class, and I’m learning so much. I liked
getting into CSS a little and making things more customizable. I found
it interesting that two elements make your content look the same but
have different meanings.”
I want to end things with a few
choice quotes from students who completed my course in the last term. I
share them not as ego boosters but as a reminder that simplicity is still alive, well, and good on the web. While many new developers feel pressured to earn their “full stack” merit badge,
the best way to learn the web — and make people excited about it — is
still the simple “a-ha!” moment that happens when someone combines HTML
with CSS for the first time in a static file.
“I can
confidently say that among all the courses I’ve taken, this is the first
one where I thoroughly read all the content and watched all the videos
in detail because it is so well-structured. Despite the complexity of
the subject, you made this course seem surprisingly easy to grasp.”
“Man,
I’ve learned so much in this class this semester, and it’s finally
over. This final project has given me more confidence and ability to
troubleshoot and achieve my vision.”
“Even
though I did not pass, I still truly did enjoy your class. It made me
feel smart because coding had felt like an impossible task before.”
“I
especially appreciate Geoff’s enthusiasm for multiple reasons. I am
hoping to change careers, and the classes are helping me get closer to
that reality.”
These are new people entering the field
for the first time who are armed with a solid understanding of the
basics and a level of curiosity and excitement that easily could clear
the height of Mount Elbert.
Isn’t that what we want? What would the web look like if we treat the next wave of web developers like first-class citizens by lowering the barriers to entry
and rolling out the red carpet for them to crack into a career in
front-end? The web is still a big place, and there is room for everyone
to find their own groove. Some things tend to flourish when we democratize them,
and many of us experienced that first-hand when we first sat down and
wrote HTML for the very first time without the benefit of organized
courses, bootcamps, YouTube channels, or frameworks to lean on. The same
magic that sparked us is still there to spark others after all this
time, even if we fail to see it.
An
overwhelming number of frameworks and tooling available today gives the
impression that web development has gotten perhaps too complex. As a
newcomer, it can be frightening to have so many to consider, almost
creating a fear of missing out that we see exploited to sell courses and
tutorials on the new hot framework that you “cannot work without.” But
perhaps that is just an exaggeration? Here it explores
those claims and finds out if web development really is that complex
and, most importantly, how we can prevent it from getting even more
difficult than we already perceive it to be.
Front-end
development seemed simpler in the early 2000s, didn’t it? The standard
website consisted mostly of static pages made of HTML and CSS seasoned
with a pinch of JavaScript and jQuery. I mean, who doesn’t miss the
cross-browser compatibility days, right?
Fast forward to today,
and it looks like a parallel universe is taking place with an
overwhelming number of choices. Which framework should you use for a new
project? Perhaps more established ones like React, Angular, Vue,
Svelte, or maybe the hot new one that came out last month? Each
framework comes with its unique ecosystem. You also need to decide
whether to use TypeScript over vanilla JavaScript and choose how to
approach server-side rendering (or static site generation) with meta-frameworks
like Next, Nuxt, or Gatsby. And we can’t forget about unit and
end-to-end testing if you want a bug-free web app. And we’ve barely
scratched the surface of the front-end ecosystem!
But has it really
gotten more complex to build websites? A lot of the frameworks and
tooling we reach for today were originally crafted for massive projects.
As a newcomer, it can be frightening to have so many to consider,
almost creating a fear of missing out that we see exploited to sell
courses and tutorials on the new hot framework that you “cannot work
without.”
All this gives the impression that web development has gotten perhaps too
complex. But maybe that is just an exaggeration? In this article, I
want to explore those claims and find out if web development really is
that complex and, most importantly, how we can prevent it from getting
even more difficult than we already perceive it to be.
How It Was Before
As
someone who got into web development after 2010, I can’t testify to my
own experience about how web development was from the late 1990s through
the 2000s. However, even fifteen years ago, learning front-end
development was infinitely simpler, at least to me. You could get a
website started with static HTML pages, minimal CSS for styling, and a
sprinkle of JavaScript (and perhaps a touch of jQuery) to add
interactive features, from toggled sidebars to image carousels and other
patterns. Not much else was expected from your average developer beyond
that — everything else was considered “going the extra mile.” Of
course, the awesome native CSS and JavaScript features we have today
weren’t around back then, but they were also unnecessary for what was
considered best practice in past years.
Large and dynamic web apps
certainly existed back then — YouTube and Facebook, to name a couple —
but they were developed by massive companies. No one was expected to
re-create that sort of project on their own or even a small team. That
would’ve been the exception rather than the norm.
I remember back
then, tend to worry more about things like SEO and page optimization
than how my IDE was configured, but only to the point of adding meta
tags and keywords because best practices didn’t include minifying all
your assets, three shaking your code, caching your site on edge CDNs, or
rendering your content on the server (a problem created by modern
frameworks along hydration).
Other factors like accessibility, user experience, and responsive
layouts were also largely overlooked in comparison to today’s standards.
Now, they are deeply analyzed and used to boost Lighthouse scores and
impress search engine algorithms.
The web and everything around it
changed as more capabilities were added and more and more people grew
to depend on it. We have created new solutions, new tools, new
workflows, new features, and whatever else new that is needed to cater
to a bigger web with even bigger needs.
The web has always had its
problems in the past that were worthy of fixing: I absolutely don’t
miss tables and float layouts, along with messy DOM manipulation. This
post isn’t meant to throw shade on new advances while waxing nostalgic
about the good days of the “old wild web.” At the same time, though,
yesterday’s problems seem infinitely simpler than those we face today.
JavaScript Frameworks
JavaScript
frameworks, like Angular and React, were created by Google and
Facebook, respectively, to be used in their own projects and satisfy the
needs that only huge web-based companies like them have. Therein lies
the main problem with web complexity: JavaScript frameworks were originally created to sustain giant projects rather than smaller ones.
Many developers vastly underestimate the amount of time it takes to
build a codebase that is reliable and maintainable with a JavaScript
framework. However, the alternative of using vanilla JavaScript was worse,
and jQuery was short for the task. Vanilla JavaScript was also unable
to evolve quickly enough to match our development needs, which changed
from simple informative websites to dynamic apps. So, many of us have
quickly adopted frameworks to avoid directly mingling with JavaScript
and its messy DOM manipulation.
Back-end development is a
completely different topic, subject to its own complexities. I only want
to focus on front-end development because that is the discipline that
has perhaps overstepped its boundaries the most by bleeding into
traditional back-end concerns.
Stacks Getting Bigger
It
was only logical for JavaScript frameworks to grow in size over time.
The web is a big place, and no one framework can cover everything. But
they try, and the complexity, in turn, increases. A framework’s size
seems to have a one-to-one correlation with its complexity.
But
the core framework is just one piece of a web app. Several other
technologies make up what’s known as a tech “stack,” and with the web
gaining more users and frameworks catering to their needs, tech stacks
are getting bigger and bigger. You may have seen popular stacks such as
MEAN (MongoDB, Express, Angular, and Node) or its React (MERN) and Vue
(MEVN) variants. These stacks are marketed as mature, test-proofed
foundations suitable for any front-end project. That means the advertised size of a core framework is grossly underestimated because they rely on other micro-frameworks to ensure highly reliable architectures, as you can see in stackshare.io.
Besides, there isn’t a one-size-fits-all stack; the best tool has
always depended — and will continue to depend — on the needs and goals
of your particular project.
This means that each new project
likely requires a unique architecture to fulfill its requirements. Giant
tech companies need colossal architectures across all their projects,
and their stacks are highly engineered accordingly to secure scalability
and maintenance. They also have massive customer bases, so maintaining a
large codebase will be easier with more revenue, more engineers, and a
clearer picture of the problem. To minimize waste, the tech stacks of
smaller companies and projects can and should be minimized not only to
match the scale of their needs but to the abilities of the developers on
the team as well.
The
idea that web development is getting too complex comes from buying into
the belief that we all have the same needs and resources as giant
enterprises.
“
Trying
to imitate their mega stacks is pointless. Some might argue that it’s a
sacrifice we have to make for future scalability and maintenance, but
we should focus first on building great sites for the user without
worrying about features users might need in the future. If what
we are building is worth pursuing, it will reach the point where we
need those giant architectures in good time. Cross that bridge when we
get there. Otherwise, it’s not unlike wearing Shaquille O’Neal-sized
sneakers in hopes of growing into them. They might not even last until
then if it happens at all!
We must remember that the end-user experience is the focus at the end of the day, and users neither care about nor know what stack we use in our apps.
What they care about is a good-looking, useful website where they can
accomplish what they came for, not the technology we use to achieve it.
This is how I’ve come to believe that web development is not
getting more complex. It’s developers like us who are perpetuating it by
buying into solutions for problems that do not need to be solved at a
certain scale.
Let me be really clear: I am not saying that
today’s web development is all bad. Indeed, we’ve realized a lot of
great features, and many of them are thanks to JavaScript frameworks
that have pushed for certain features. jQuery had that same influence on
JavaScript for many, many years.
We can still create minimum
viable products today with minimal resources. No, those might not make
people smash the Like button on your social posts, but they meet the
requirements, nothing more and nothing less. We want bigger! Faster!
Cheaper! But we can’t have all three.
If anything, front-end development has gotten way easier
thanks to modern features that solve age-old development issues, like
the way CSS Flexbox and Grid have trivialized layouts that used to
require complex hacks involving floats and tables. It’s the same deal
with JavaScript gaining new ways to build interactions that used to take
clever workarounds or obtuse code, such as having the Intersection Observer API to trivialize things like lazy loading (although HTML has gained its own features in that area, too).
Each
project, regardless of its simplicity, desperately needs a JavaScript
framework. A project without a complex framework is like serving caviar
on a paper plate.
At least, that’s what everyone seems to think.
But is that actually true? I’d argue on the contrary. JavaScript
frameworks are best used on bigger applications. If you’re working on a
smaller project, a component-based framework will only complicate
matters, making you split your website into a component hierarchy that
amounts to overkill for small projects.
The idea of needing a framework for everything has been massively oversold.
Maybe not directly, but you unconsciously get that feeling whenever a
framework’s name pops in, as Edge engineer Alex Russell eloquently
expresses in his article, “The Market For Lemons”:
“These
technologies were initially pitched on the back of “better user
experiences” but have utterly failed to deliver on that promise outside
of the high-management-maturity organisations in which they were born.
Transplanted into the wider web, these new stacks have proven to be
expensive duds.”
— Alex Russell
Remember, the purpose of a framework is to simplify your life and save time.
If the project you’re working on is smaller, the time you supposedly
save is likely overshadowed by the time you spend either setting up the
framework or making it work with the rest of the project. A framework
can help make bigger web apps more interactive and dynamic, but there
are times when a framework is a heavy-handed solution that actually
breeds inefficient workflows and introduces technical debt.
Step
back and think about this: Are HTML, CSS, and a touch of JavaScript
enough to build your website or web application? If so, then stick with
those. What I am afraid of is adding complexity for complexity’s sake
and inadvertently raising the barrier to entry for those coming into web
development. We can still accomplish so much with HTML and CSS alone,
thanks again to many advances in the last decade. But we give the
impression that they are unsuitable for today’s web consumption and need
to be enhanced.
Knowing Everything And Nothing At The Same Time
The
perceived standard that teams must adopt framework-centered
architectures puts a burden not only on the project itself but on a
developer’s well-being, too. As mentioned earlier, most teams are unable
to afford those architectures and only have a few developers to
maintain them. If we undermine what can be achieved with HTML and CSS
alone and set the expectations that any project — regardless of size —
needs to have a bleeding edge stack, then the weight to meet
those expectations falls on the developer’s shoulders, with the great
responsibility of being proficient in all areas, from the server and
database to front end, to design, to accessibility, to performance, to
testing, and it doesn’t stop. It’s what has been driving “The Great Divide” in front-end development, which Chris Coyier explains like this:
“The
divide is between people who self-identify as a (or have the job title
of) front-end developer yet have divergent skill sets. On one side, an army of developers whose interests, responsibilities, and skillsets are heavily revolved around JavaScript. On the other,
an army of developers whose interests, responsibilities, and skillsets
are focused on other areas of the front end, like HTML, CSS, design,
interaction, patterns, accessibility, and so on.”
— Chris Coyier
Under
these expectations, developers who focus more on HTML, CSS, design, and
accessibility rather than the latest technology will feel less valued
in an industry that appears to praise those who are concerned with the
stack. What exactly are we saying when we start dividing
responsibilities in terms of “full-stack development” or absurd terms
like “10x development”? A while back, Brad Frost began distinguishing these divisions as “front-of-the-front-end” and “back-of-the-front-end”.
Mandy Michael explains what impact the chase for “full-stack” has had on developers trying to keep up:
“The
worst part about pushing the “know everything” mentality is that we end
up creating an industry full of professionals suffering from burnout
and mental illness. We have people speaking at conferences about
well-being, imposter syndrome, and full-stack anxiety, yet despite that,
we perpetuate this idea that people have to know everything and be
amazing at it.”
— Mandy Michael
This isn’t the
only symptom of adopting heavy-handed solutions for what “vanilla” HTML,
CSS, and JavaScript already handle nicely. As the expectations for what
we can do as front-end developers grow, the learning curve of front-end
development grows as well. Again, we can’t learn and know everything in
this vast discipline. But we tell ourselves we have to, and thanks to
this mentality, it’s unfortunately common to witness developers who may
be extremely proficient with a particular framework but actually know
and understand little of the web platform itself, like HTML semantics
and structure.
The
fact that many budding developers tend to jump straight into frameworks
at the expense of understanding the basics of HTML and CSS isn’t a new
worry, as Rachel Andrew discussed back in 2019:
“That’s
the real entry point here, and yes, in 2019, they are going to have to
move on quickly to the tools and techniques that will make them
employable, if that is their aim. However, those tools output HTML and
CSS in the end. It is the bedrock of everything that we do, which makes
the devaluing of those with real deep skills in those areas so much more
baffling.”
— Rachel Andrew
And I want to clarify yet again that modern
Javascript frameworks and libraries aren’t inherently bad; they just
aren’t designed to replace the web platform and its standards. But we keep pushing them like we want them to!
The Consequences Of Vendor Lock-In
“Vendor
lock-in” happens when we depend too deeply on proprietary products and
services to the extent that switching to other products and services
becomes a nearly impossible task. This often occurs when cloud services
from a particular company are deeply integrated into a project. It’s an
issue, especially in cloud computing, since moving databases once they
are set up is expensive and lengthy.
Vendor lock-in in web
development has traditionally been restricted to the back end, like with
cloud services such as AWS or Firebase; the front-end framework,
meanwhile, was a completely separate concern. That said, I have noticed a
recent trend where vendor lock-in is reaching into meta-frameworks,
too. With the companies behind certain meta-frameworks offering hosting
services for their own products, swapping hosts is increasingly harder
to do (whether the lock-in is designed intentionally or not). Of course,
companies and developers will be more likely to choose the hosting
service of the company that made a particular framework used on their
projects — they’re the experts! — but that only increases the project’s
dependency on those vendors and their services.
A clear example is
the relationship between Next and Vercel, the parent cloud service for
Next. With the launch of Next 13, it has become increasingly harder to
set up a Next project outside of Vercel, leading to projects like Open Next, which says right on its website that “[w]hile
Vercel is great, it’s not a good option if all your infrastructure is
on AWS. Hosting it in your AWS account makes it easy to integrate with
your backend [sic]. And it’s a lot cheaper than Vercel.” Fortunately, the developers’ concerns have been heard, and Next 14 brings clarity on how to self-host Next on a Node server.
Another example is Gatsby and Gatsby Cloud.
Gatsby has always offered helpful guides and alternative hosting
recommendations, but since the launch of Gatsby Cloud in 2019, the main
framework has been optimized so that using Gatsby and Gatsby Cloud
together requires no additional hosting configurations. That’s fantastic
if you adopt both, but it’s not so great if all you need is one or the
other because integrating the framework with other hosts — and vice
versa — is simply harder. It’s as if you are penalized for exercising
choice.
And let’s not forget that no team expected Netlify to acquire Gatsby Cloud in February 2023.
This is a prime case where the vendor lock-in problem hits everybody
because converting from one site to another comes at a cost. Some teams
were charged 120% more after converting from Gatsby Cloud to Netlify —
even with the same plan they had with Gatsby Cloud!
What’s the
solution? The common answer I hear is to stop using paid cloud services
in favor of open-sourced alternatives. While that’s great and indeed a
viable option for some projects, it fails to consider that an open-source project may not meet the requirements needed for a given app.
And
even then, open-source software depends on the community of developers
that maintain and update the codebase with little to no remuneration in
exchange. Further, open source is equally prone to locking you into
certain solutions that are designed to solve a deficiency with the
software.
There are frameworks and libraries, of course, that are
in no danger of being abandoned. React is a great example because it has
an actively engaged community behind it. But you can’t have the same
assurance with each new dependency you add to a project. We can’t simply
keep installing more packages and components each time we spot a weak
spot in the dependency chain, especially when a project is perfectly
suited for a less complex architecture that properly leverages the web
platform.
Those
are virtually the only two choices. Many of the teams I know or have
worked on depend on third-party services because they cannot afford to
develop them on their own; that’s a luxury that only massive companies
can afford. It’s a problem we have to undergo when starting a new
project, but one we can minimize by reducing the number of dependencies
and choosing wisely when we have to.
Each Solution Introduces A New Problem
Why
exactly have modern development stacks gotten so large and complex? We
can point a finger at the “Development Paradox.” With each new framework
or library, a new problem crops up, and time-starved developers spend
months developing a new tool to solve that problem. And when there isn’t
a problem, don’t worry — we will create one eventually. This is a feedback loop that creates amazing solutions and technologies but can lead to over-engineered websites if we don’t reign it in.
This reminds me of the famous quote:
“The
plain fact is that if you don’t have a problem, you create one. If you
don’t have a problem, you don’t feel that you are living.”
— U.G. Krishnamurti
Let’s look specifically at React. It was originally created by Facebook for Facebook to develop more dynamic features for users while improving Facebook’s developer experience.
Since React was open-sourced in 2013 (and nearly re-licensed in 2017, if it weren’t for the WordPress community),
hundreds of new utilities have been created to address various
React-specific problems. How do you start a React project? There’s
Create React App and Vite. Do you need to enhance your state management?
There is Redux, among other options. Need help creating forms? There is
a React Hook Form. And perhaps the most important question: Do you need
server-side rendering? There’s Next, Remix, or Gatsby for that. Each
solution comes with its own caveats, and developers will create their
own solutions for them.
It may be unfair to pick on React since it considers itself a library, not a framework.
It’s inevitably prone to be extended by the community. Meanwhile,
Angular and Vue are frameworks with their own community ecosystems. And
this is the tip of the iceberg since there are many JavaScript
frameworks in the wild, each with its own distinct ideology and
dependencies.
Again, I don’t want you to get the wrong idea. I love
that new technologies emerge and find it liberating to have so many
options. But when building something as straightforward as a webpage or
small website — which some have started referring to as “multi-page
applications” — we have to draw a line that defines how many new
technologies we use and how reliable they are. We’re quite literally
mashing together third-party code written by various third-party
developers. What could go wrong? Please don’t answer that.
Remember that our users don’t care what’s in our stacks.
They only see the final product, so we can save ourselves from working
on unnecessary architectures that aren’t appreciated outside of
development circles. It may seem counterintuitive in the face of
advancing technology, but knowing that the user doesn’t care about what
goes behind the scenes and only sees the final product will
significantly enhance our developer experience and free you from locked
dependencies. Why fix something that isn’t broken?
How Can We Simplify Our Codebases?
We’ve
covered several reasons why web development appears to be more complex
today than in years past, but blaming developers for releasing new
utilities isn’t an accurate portrayal of the real problem. After all,
when developing a site, it’s not like we are forced to use each new
technology that enters the market. In fact, many of us are often unaware
of a particular library and only learn about it when developing a new
feature. For example, if we want to add toast notifications to our web app, we will look for a library like react-toastify
rather than some other way of building them because it “goes with” that
specific library. It’s worth asking whether the app needs toast
notifications at all if they introduce new dependencies.
Imagine
you are developing an app that allows users to discover, review, and
rate restaurants in their area. The app needs, at a bare minimum,
information about each restaurant, a search tool to query them, and an
account registration flow with authentication to securely access the
account. It’s easy to make assumptions about what a future user might
need in addition to these critical features. In many cases, a project
ends up delayed because we add unnecessary features like SSR,
notifications, offline mode, and fancy animations — sometimes before the
app has even converted its first registered user!
I believe we
can boil down the complexity problem to personal wishes and perceived
needs rather than properly scoping a project based on user needs and
experiences.
That level of scope creep can easily turn into an over-engineered product that will likely never see the light of launching.
What
can we do to simplify our own projects? The following advice is
relevant when you have control over your project, either because it’s a
personal one, it’s a smaller one for a smaller team, or you have control
over the decisions in whatever size organization you happen to be in.
The hardest and most important step is having a sense of detection when your codebase is getting unnecessarily complicated.
I deem it the hardest step because there is no certainty of what the
requirements are or what the user needs; we can only make assumptions.
Some are obvious, like assuming the user will need a way to log into the
app. Others might be unclear, like whether the app should have private
messaging between users. Others are still far-fetched, like believing
users need extremely low latency in an e-commerce page. Other features
are in the “nice to have” territory.
That is regarding the user experience, but the same questions emerge on the development side:
Should we be using a CSS preprocessor or a CSS framework, or can we achieve it using only CSS modules?
Is vanilla JavaScript enough, or are we going to add TypeScript?
Does the app need SSR, SSG, or a hybrid of the two?
Should we implement Redis on the back end for faster database queries, or is that too much scope for the work?
Should we be implementing end-to-end testing or unit tests?
These
are valid questions that should be considered when developing a site,
but they can distract us from our main focus: getting things done.
“Done is better than perfect.”
— Sheryl Sandberg
And, hey, even the largest and most sophisticated apps began as minimal offerings that iterated along the way.
We also ought to be asking ourselves what would happen if a particular feature or dependency isn’t added to the project. If the answer is “nothing,” then we should be shifting our attention to something else.
Another question worth asking: “Why are we choosing to add [X]?”
Is it because that’s what is popular at the moment, or because it
solves a problem affecting a core feature? Another aspect to take into
consideration is how familiar we are with certain technologies and give
preference to those we know and can start using them right away rather
than having to stop and learn the ins and outs of a new framework.
Choose
the right tool for the job, which is going to be the one that meets the
requirements and fits your mental model. Focus less on a library’s
popularity and scalability but rather on getting your app to the point
where it needs to scale in the first place.
Conclusion
It’s incredibly difficult to not
over-engineer web apps given current one-size-fits-all and
fear-of-missing-out mentalities. But we can be more conscious of our
project goals and exercise vigilance in guarding our work against scope
creep. The same can be applied to the stack we use, making choices based
on what is really needed rather than focusing purely on what everyone
else is using for their particular work.
After reading the word
“framework” exactly 48 times in this article, can we now say the web is
getting too complex? It has been complex by nature since its origins,
but complexity doesn’t translate to “over-engineered” web apps.
The web isn’t intrinsically over-engineered, and we only have ourselves
to blame for over-engineering our projects with overly-wrought
solutions for perceived needs.