javascript framework – CSS-Tricks https://css-tricks.com Tips, Tricks, and Techniques on using Cascading Style Sheets. Thu, 09 Feb 2023 19:45:53 +0000 en-US hourly 1 https://wordpress.org/?v=6.2.2 https://i0.wp.com/css-tricks.com/wp-content/uploads/2021/07/star.png?fit=32%2C32&ssl=1 javascript framework – CSS-Tricks https://css-tricks.com 32 32 45537868 Healthcare, Selling Lemons, and the Price of Developer Experience https://css-tricks.com/healthcare-selling-lemons-and-the-price-of-developer-experience/ https://css-tricks.com/healthcare-selling-lemons-and-the-price-of-developer-experience/#comments Thu, 09 Feb 2023 19:45:48 +0000 https://css-tricks.com/?p=377169 Every now and then, a one blog post is published and it spurs a reaction or response in others that are, in turn, published as blogs posts, and a theme starts to emerge. That’s what happened this past week and …


Healthcare, Selling Lemons, and the Price of Developer Experience originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Every now and then, a one blog post is published and it spurs a reaction or response in others that are, in turn, published as blogs posts, and a theme starts to emerge. That’s what happened this past week and the theme developed around the cost of JavaScript frameworks — a cost that, in this case, reveals just how darn important it is to use JavaScript responsibly.

Eric Bailey: Modern Health, frameworks, performance, and harm

This is where the story begins. Eric goes to a health service provider website to book an appointment and gets… a blank screen.

In addition to a terrifying amount of telemetry, Modern Health’s customer-facing experience is delivered using React and Webpack.

If you are familiar with how the web is built, what happened is pretty obvious: A website that over-relies on JavaScript to power its experience had its logic collide with one or more other errant pieces of logic that it summons. This created a deadlock.

If you do not make digital experiences for a living, what happened is not obvious at all. All you see is a tiny fake loading spinner that never stops.

D’oh. This might be mere nuisance — or even laughable — in some situations, but not when someone’s health is on the line:

A person seeking help in a time of crisis does not care about TypeScript, tree shaking, hot module replacement, A/B tests, burndown charts, NPS, OKRs, KPIs, or other startup jargon. Developer experience does not count for shit if the person using the thing they built can’t actually get what they need.

This is the big smack of reality. What happens when our tooling and reporting — the very things that are supposed to make our work more effective — get in the way of the user experience? These are tools that provide insights that can help us anticipate a user’s needs, especially in a time of need.

I realize that pointing the finger at JavaScript frameworks is already divisive. But this goes beyond whether you use React or framework d’jour. It’s about business priorities and developer experience conflicting with user experiences.

Alex Russell: The Market for Lemons

Partisans for slow, complex frameworks have successfully marketed lemons as the hot new thing, despite the pervasive failures in their wake, crowding out higher-quality options in the process.

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.

There’s the rub. Alex ain’t mincing words, but notice that the onus is on the way frameworks haved been marketed to developers than developers themselves. The sales pitch?

Once the lemon sellers embed the data-light idea that improved “Developer Experience” (“DX”) leads to better user outcomes, improving “DX” became and end unto itself, and many who knew better felt forced to play along. The long lead times in falsifying trickle-down UX was a feature, not a bug; they don’t need you to succeed, only to keep buying.

As marketing goes, the “DX” bait-and-switch is brilliant, but the tech isn’t delivering for anyone but developers.

Tough to stomach, right? No one wants to be duped, and it’s tough to admit a sunken cost when there is one. It gets downright personal if you’ve invested time in a specific piece of tech and effort integrating it into your stack. Development workflows are hard and settling into one is sorta like settling into a house you plan on living in a little while. But you’d want to know if your house was built on what Alex calls a “sandy foundation”.

I’d just like to pause here a moment to say I have no skin in this debate. As a web generalist, I tend to adopt new tools early for familiarity then drop them fast, relegating them to my toolshed until I find a good use for them. In other words, my knowledge is wide but not very deep in one area or thing. HTML, CSS, and JavaScript is my go-to cocktail, but I do care a great deal about user experience and know when to reach for a tool to solve a particular thing.

And let’s acknowledge that not everyone has a say in the matter. Many of us work on managed teams that are prescribed the tools we use. Alex says as much, which I think is important to call out because it’s clear this isn’t meant to be personal. It’s a statement on our priorities and making sure they along to user expectations.

Let’s alow Chris to steer us back to the story…

Chris Coyier: End-To-End Tests with Content Blockers?

So, maybe your app is built on React and it doesn’t matter why it’s that way. There’s still work to do to ensure the app is reliable and accessible.

Just blocking a file shouldn’t totally wreck a website, but it often does! In JavaScript, that may be because the developers have written first-party JavaScript (which I’ll generally allow) that depends on third-party JavaScript (which I’ll generally block).

[…]

If I block resources from tracking-website.com, now my first-party JavaScript is going to throw an error. JavaScript isn’t chill. If an error is thrown, it doesn’t execute more JavaScript further down in the file. If further down in that file is transitionToOnboarding();— that ain’t gonna work.

Maybe it’s worth revisiting your workflow and tweaking it to account to identify more points of failure.

So here’s an idea: Run your end-to-end tests in browsers that have popular content blockers with default configs installed. 

Doing so may uncover problems like this that stop your customers, and indeed people in need, from being stopped in their tracks.

Good idea! Hey, anything that helps paint a more realistic picture of how the app is used. That sort of clarity could happen a lot earlier in the process, perhaps before settling on development decisions. Know your users. Why are they using the app? How do they browse the web? Where are they phsically located? What problems could get in their way? Chris has a great talk on that, too.


Healthcare, Selling Lemons, and the Price of Developer Experience originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/healthcare-selling-lemons-and-the-price-of-developer-experience/feed/ 3 377169
Introduction to the Solid JavaScript Library https://css-tricks.com/introduction-to-the-solid-javascript-library/ https://css-tricks.com/introduction-to-the-solid-javascript-library/#comments Tue, 24 Aug 2021 14:30:50 +0000 https://css-tricks.com/?p=346597 Solid is a reactive JavaScript library for creating user interfaces without a virtual DOM. It compiles templates down to real DOM nodes once and wraps updates in fine-grained reactions so that when state updates, only the related code runs.

This …


Introduction to the Solid JavaScript Library originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Solid is a reactive JavaScript library for creating user interfaces without a virtual DOM. It compiles templates down to real DOM nodes once and wraps updates in fine-grained reactions so that when state updates, only the related code runs.

This way, the compiler can optimize initial render and the runtime optimizes updates. This focus on performance makes it one of the top-rated JavaScript frameworks.

I got curious about it and wanted to give it a try, so I spent some time creating a small to-do app to explore how this framework handles rendering components, updating state, setting up stores, and more.

Here’s the final demo if you just can’t wait to see the final code and result:

Getting started

Like most frameworks, we can start by installing the npm package. To use the framework with JSX, run:

npm install solid-js babel-preset-solid

Then, we need to add babel-preset-solid to our Babel, webpack, or Rollup config file with:

"presets": ["solid"]

Or if you’d like to scaffold a small app, you can also use one of their templates:

# Create a small app from a Solid template
npx degit solidjs/templates/js my-app
 
# Change directory to the project created
cd my-app
 
# Install dependencies
npm i # or yarn or pnpm
 
# Start the dev server
npm run dev

There is TypeScript support so if you’d like to start a TypeScript project, change the first command to npx degit solidjs/templates/ts my-app.

Creating and rendering components

To render components, the syntax is similar to React.js, so it might seem familiar:

import { render } from "solid-js/web";
 
const HelloMessage = props => <div>Hello {props.name}</div>;
 
render(
 () => <HelloMessage name="Taylor" />,
 document.getElementById("hello-example")
);

We need to start by importing the render function, then we create a div with some text and a prop, and we call render, passing the component and the container element.

This code then compiles down to real DOM expressions. For example, the code sample above, once compiled by Solid, looks something like this:

import { render, template, insert, createComponent } from "solid-js/web";
 
const _tmpl$ = template(`<div>Hello </div>`);
 
const HelloMessage = props => {
 const _el$ = _tmpl$.cloneNode(true);
 insert(_el$, () => props.name);
 return _el$;
};
 
render(
 () => createComponent(HelloMessage, { name: "Taylor" }),
 document.getElementById("hello-example")
);

The Solid Playground is pretty cool and shows that Solid has different ways to render, including client-side, server-side, and client-side with hydration.

Tracking changing values with Signals

Solid uses a hook called createSignal that returns two functions: a getter and a setter. If you’re used to using a framework like React.js, this might seem a little weird. You’d normally expect the first element to be the value itself; however in Solid, we need to explicitly call the getter to intercept where the value is read in order to track its changes.

For example, if we’re writing the following code:

const [todos, addTodos] = createSignal([]);

Logging todos will not return the value, but a function instead. If we want to use the value, we need to call the function, as in todos().

For a small todo list, this would be:

import { createSignal } from "solid-js";
 
const TodoList = () => {
 let input;
 const [todos, addTodos] = createSignal([]);
 
 const addTodo = value => {
   return addTodos([...todos(), value]);
 };
 
 return (
   <section>
     <h1>To do list:</h1>
     <label for="todo-item">Todo item</label>
     <input type="text" ref={input} name="todo-item" id="todo-item" />
     <button onClick={() => addTodo(input.value)}>Add item</button>
     <ul>
       {todos().map(item => (
         <li>{item}</li>
       ))}
     </ul>
   </section>
 );
};

The code sample above would display a text field and, upon clicking the “Add item” button, would update the todos with the new item and display it in a list.

This can seem pretty similar to using useState, so how is using a getter different? Consider the following code sample:

console.log("Create Signals");
const [firstName, setFirstName] = createSignal("Whitney");
const [lastName, setLastName] = createSignal("Houston");
const [displayFullName, setDisplayFullName] = createSignal(true);
 
const displayName = createMemo(() => {
 if (!displayFullName()) return firstName();
 return `${firstName()} ${lastName()}`;
});
 
createEffect(() => console.log("My name is", displayName()));
 
console.log("Set showFullName: false ");
setDisplayFullName(false);
 
console.log("Change lastName ");
setLastName("Boop");
 
console.log("Set showFullName: true ");
setDisplayFullName(true);

Running the above code would result in:

Create Signals
 
My name is Whitney Houston
 
Set showFullName: false
 
My name is Whitney
 
Change lastName
 
Set showFullName: true
 
My name is Whitney Boop

The main thing to notice is how My name is ... is not logged after setting a new last name. This is because at this point, nothing is listening to changes on lastName(). The new value of displayName() is only set when the value of displayFullName() changes, this is why we can see the new last name displayed when setShowFullName is set back to true.

This gives us a safer way to track values updates.

Reactivity primitives

In that last code sample, I introduced createSignal, but also a couple of other primitives: createEffect and createMemo.

createEffect

createEffect tracks dependencies and runs after each render where a dependency has changed.

// Don't forget to import it first with 'import { createEffect } from "solid-js";'
const [count, setCount] = createSignal(0);
 
createEffect(() => {
 console.log("Count is at", count());
});

Count is at... logs every time the value of count() changes.

createMemo

createMemo creates a read-only signal that recalculates its value whenever the executed code’s dependencies update. You would use it when you want to cache some values and access them without re-evaluating them until a dependency changes.

For example, if we wanted to display a counter 100 times and update the value when clicking on a button, using createMemo would allow the recalculation to happen only once per click:

function Counter() {
   const [count, setCount] = createSignal(0);
   // Calling `counter` without wrapping it in `createMemo` would result in calling it 100 times.
   // const counter = () => {
   //    return count();
   // }
 
   // Calling `counter` wrapped in `createMemo` results in calling it once per update.
// Don't forget to import it first with 'import { createMemo } from "solid-js";'
   const counter = createMemo(() => {
       return count()
   })
 
   return (
       <>
       <button onClick={() => setCount(count() + 1)}>Count: {count()}</button>
       <div>1. {counter()}</div>
       <div>2. {counter()}</div>
       <div>3. {counter()}</div>
       <div>4. {counter()}</div>
       <!-- 96 more times -->
       </>
   );
}

Lifecycle methods

Solid exposes a few lifecycle methods, such as onMount, onCleanup and onError. If we want some code to run after the initial render, we need to use onMount:

// Don't forget to import it first with 'import { onMount } from "solid-js";'
 
onMount(() => {
 console.log("I mounted!");
});

onCleanup is similar to componentDidUnmount in React — it runs when there is a recalculation of the reactive scope.

onError executes when there’s an error in the nearest child’s scope. For example we could use it when fetching data fails.

Stores

To create stores for data, Solid exposes createStore which return value is a readonly proxy object and a setter function.

For example, if we changed our todo example to use a store instead of state, it would look something like this:

const [todos, addTodos] = createStore({ list: [] });
 
createEffect(() => {
 console.log(todos.list);
});
 
onMount(() => {
 addTodos("list", [
   ...todos.list,
   { item: "a new todo item", completed: false }
 ]);
});

The code sample above would start by logging a proxy object with an empty array, followed by a proxy object with an array containing the object {item: "a new todo item", completed: false}.

One thing to note is that the top level state object cannot be tracked without accessing a property on it — this is why we’re logging todos.list and not todos.

If we only logged todo` in createEffect, we would be seeing the initial value of the list but not the one after the update made in onMount.

To change values in stores, we can update them using the setting function we define when using createStore. For example, if we wanted to update a todo list item to “completed” we could update the store this way:

const [todos, setTodos] = createStore({
 list: [{ item: "new item", completed: false }]
});
 
const markAsComplete = text => {
 setTodos(
   "list",
   i => i.item === text,
   "completed",
   c => !c
 );
};
 
return (
 <button onClick={() => markAsComplete("new item")}>Mark as complete</button>
);

Control Flow

To avoid wastefully recreating all the DOM nodes on every update when using methods like .map(), Solid lets us use template helpers.

A few of them are available, such as For to loop through items, Show to conditionally show and hide elements, Switch and Match to show elements that match a certain condition, and more!

Here are some examples showing how to use them:

<For each={todos.list} fallback={<div>Loading...</div>}>
 {(item) => <div>{item}</div>}
</For>
 
<Show when={todos.list[0].completed} fallback={<div>Loading...</div>}>
 <div>1st item completed</div>
</Show>
 
<Switch fallback={<div>No items</div>}>
 <Match when={todos.list[0].completed}>
   <CompletedList />
 </Match>
 <Match when={!todos.list[0].completed}>
   <TodosList />
 </Match>
</Switch>

Demo project

This was a quick introduction to the basics of Solid. If you’d like to play around with it, I made a starter project you can automatically deploy to Netlify and clone to your GitHub by clicking on the button below!

This project includes the default setup for a Solid project, as well as a sample Todo app with the basic concepts I’ve mentioned in this post to get you going!

There is much more to this framework than what I covered here so feel free to check the docs for more info!


Introduction to the Solid JavaScript Library originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/introduction-to-the-solid-javascript-library/feed/ 9 346597
Slinkity https://css-tricks.com/slinkity/ https://css-tricks.com/slinkity/#respond Mon, 26 Jul 2021 14:36:04 +0000 https://css-tricks.com/?p=345288 Perhaps the #1 reason I love Astro is that it brings the JavaScript component authoring experience to the Static Site Generator world with zero JavaScript (except bits you very specifically opt-in to). That HTML-first approach is also why I like …


Slinkity originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Perhaps the #1 reason I love Astro is that it brings the JavaScript component authoring experience to the Static Site Generator world with zero JavaScript (except bits you very specifically opt-in to). That HTML-first approach is also why I like Eleventy. It’s just that, as awesome as Eleventy is, I’d prefer working in more modern components and modern templating. Plus I like the build-time JavaScript access in Astro components at my fingertips.

But what if Eleventy offered JavaScript templates also? Well it kinda does—there is a plugin eleventy-plugin-vue (official) that looks well on its way toward that end. But here’s another take on it from Ben Holmes: Slinkity. I’ll quote the bullet points:

  • 🚀 Unlocks component frameworks (React, Vue, and Svelte) for writing page templates and layout templates. So you can turn an existing .html or .liquid file into a .jsx file, and immediately start building routes on your site using React.
  • 🔖 Includes powerful shortcodes to insert components into existing pages. Add a line like this to your markdown, HTML, Nunjucks, etc, and watch the magic happen: {% react './path/to/component.jsx' %}
  • 💧 Hydrates these component-driven pages on the client. In other words, all your dynamic state management will work in development and production with 0 extra setup.
  • 🔗 (Optionally) Turns your site into a single page app. This opens the door for animated page transitions, persistent state between pages, and more!

It seems like it’s bringing the Astro vibe to Eleventy. It even uses Snowpack, which is the build tool by the Astro team.

To Shared LinkPermalink on CSS-Tricks


Slinkity originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/slinkity/feed/ 0 345288
Astro https://css-tricks.com/astro/ https://css-tricks.com/astro/#comments Wed, 05 May 2021 21:49:23 +0000 https://css-tricks.com/?p=339563 You can’t even look at code or documentation for Astro (publicly) yet — it’s an in-progress idea — but you can watch a video of Fred showing it off to Feross.

I gotta admit: it looks awesome. I’m bullish …


Astro originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
You can’t even look at code or documentation for Astro (publicly) yet — it’s an in-progress idea — but you can watch a video of Fred showing it off to Feross.

I gotta admit: it looks awesome. I’m bullish on two major parts of this:

  1. Jamstack is a good idea. Producing static, pre-rendered, minimal (or no) JavaScript pages is smart.
  2. Components are a good idea. Crafting interfaces from composable components is the correct abstraction. JavaScript does it best right now because of things like ES Modules, template literals, web components, deeply developed tooling, etc.

I’m a fan of Eleventy also, and this feels like Eleventy in a way, except that I don’t like any of the templating languages as much as I like JavaScript components.

Here’s a list of some interesting aspects:

  • Like Vue has .vue files and Svelte has .svelte files, Astro has .astro files in a unique format. I like how it enforces JavaScript-at-the-top in a Frontmatter-like format.
  • It doesn’t replace other JavaScript libraries. It’s like a site-builder framework on top of them. You can literally use React and JSX components, or Vue files, or Svelte files, including using that library’s state management solutions. You import them in your Astro files.
  • It has the-filesystem-is-the-default-router, like Next.
  • It has scoped-CSS-by-default like Vue’s <style scoped>, meaning it doesn’t even need CSS Modules since you get all the benefit anyway.
  • It ships no JavaScript to the front-end at all, unless you specifically opt-in to it (or use its :visible syntax, which injects just enough JavaScript to lazy load more as needed).
  • It embraces the idea of Islands Architecture — the idea that most sites are composed of static content with only parts of interactive/dynamic content.
  • The idea of only requesting JavaScript for interactive components if they are visible (via IntersectionObserver) is a first-class citizen of the framework — Kinda like loading="lazy" for anything interactive.
  • They credit Marko (the HTML/JavaScript-kind hybrid language) right on the homepage (for “asking the question”). Reminds me of approaches like Alpine or htmx.
  • It sneaks MDX (or the like) in there, meaning you can author content in Markdown (good) but sneak <Components /> in there too (also good).

I quite like that it doesn’t have this whole, This is a new thing! You like it! Old things are bad! New things are good! sort of vibe. Instead, it has a We’re gonna steal every last good idea we can from what came before, and lean on what the native web does best vibe which, in turn, makes me think of Baldur Bjarnason’s “Which type of novelty-seeking web developer are you?” article

Bad:

This is the first kind of novelty-seeking web developer. The type that sees history only as a litany of mistakes and that new things must be good because they are new. Why would anybody make a new thing unless it was an improvement on the status quo? Ergo, it must be an improvement on the status quo.

Good:

This is the other kind of novelty-seeking web developer, one who seeks to build on the history and nature of the web instead of trying to transform it.


Astro originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/astro/feed/ 5 339563
The Cost of Javascript Frameworks https://css-tricks.com/the-cost-of-javascript-frameworks/ Sun, 26 Apr 2020 13:30:21 +0000 https://css-tricks.com/?p=307618 I expect this post from Tim Kadlec to be quoted in every performance conference talk for the next few years. There is a lot of data here, so please check it out for yourself, but the short story is that …


The Cost of Javascript Frameworks originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
I expect this post from Tim Kadlec to be quoted in every performance conference talk for the next few years. There is a lot of data here, so please check it out for yourself, but the short story is that JavaScript-framework-powered sites are definitely heavier and more resource-intensive than non-JavaScript-framework-powered sites. Angular is the beefiest and React is hardest on the CPU. But as Tim says:

… it says very little about the performance of the core frameworks in play and much more about the approach to development these frameworks may encourage

Another big caveat is that there isn’t data here on-site usage after first-load, which is a huge aspect of “single-page app” approaches.

Still, while you can be performant with frameworks (although even that top 10% isn’t super encouraging), the frameworks aren’t doing much to help what has turned into a bad situation. It mimics exactly what we talked about recently with accessibility. It’s not the frameworks “fault” exactly, but they are also the best positioned to stop the bleeding.

To Shared LinkPermalink on CSS-Tricks


The Cost of Javascript Frameworks originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
307618
Build your own React https://css-tricks.com/build-your-own-react/ Wed, 20 Nov 2019 15:55:15 +0000 https://css-tricks.com/?p=299043 Wowza! Rodrigo Pombo’s article about how to build React from scratch is fantastic, not only because it’s well written, but because of the outstanding interaction design: each line in the code examples ge highlighted and explored in further detail as …


Build your own React originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Wowza! Rodrigo Pombo’s article about how to build React from scratch is fantastic, not only because it’s well written, but because of the outstanding interaction design: each line in the code examples ge highlighted and explored in further detail as you scroll down the page.

This makes it super easy to walk through each process step by step:

How neat is that? This definitely feels like a new way we should consider showing technical information I reckon as it’s just so much easier to read the code.

Oh, and the part about building your own React? Andy Bell advocates something similar when it comes to state management:

Libraries like Redux, MobX and Vuex make managing cross-component state almost trivial. This is great for an application’s resilience and it works really well with a state-first, reactive framework such as React or Vue.

How do these libraries work though? What would it take to write one ourselves? Turns out, it’s pretty straightforward and there’s an opportunity to learn some really common patterns and also learn about some useful modern APIs that are available to us.

Seems like Rodrigo’s pattern is a nice way to make that sort of learning possible.

To Shared LinkPermalink on CSS-Tricks


Build your own React originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
299043
Components, yo. https://css-tricks.com/components-yo/ https://css-tricks.com/components-yo/#comments Fri, 14 Jun 2019 13:57:15 +0000 http://css-tricks.com/?p=289212 I see VuePress just went 1.0. Explained simply, it’s a static site generator based on Vue. But of course, you work in Vue, which means you work in components.

All the modern JavaScript frameworks are component-based. Even …


Components, yo. originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
I see VuePress just went 1.0. Explained simply, it’s a static site generator based on Vue. But of course, you work in Vue, which means you work in components.

All the modern JavaScript frameworks are component-based. Even when they disagree with each other about specific things (like how Svelte requires compilation), they all seem to agree on the model of working in components. React is all components. A popular static site generator for React is Next.js. The Vue version of that is Nuxt.js.

Then there is Gatsby which is all React. (Listen to our latest ShopTalk Show as we discuss it.) Gridsome seems like the most 1-to-1 comparison in Vue-land, the notable comparison being how they both are designed to suck in data from any source. Components though, of course. I’m not sure there is a flagship Angular-based static site generator, but they are out there, and Angular is components all the way down.

Components are so ubiquitous that perhaps you don’t even think about it anymore. But you might feel it, particularly if you jump back and forth between projects that aren’t component-driven. WordPress development, generally, I feel, isn’t component driven. Sure, you’ve got your header.php and footer.php files and such. You can break those apart however you want, but it’s rather ad-hoc. You aren’t explicitly building components and feeding those components local data and testing them as such. (You can get a lot closer with something like Timber.)

Building front-ends out of server-side code is absolutely fine. Server-side rendering is rife with advantages. But server-side languages don’t seem to have embraced components the way JavaScript has. And since everyone seems to like components (front-end devs obviously love it, designers think that way anyway, back-end devs understand it…) it’s no surprise to me to see this surge of beloved projects build server-side (or build-time) generated sites from JavaScript, simply because it’s component-based and components are just a good idea.


Components, yo. originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/components-yo/feed/ 6 289212
STAR Apps: A New Generation of Front-End Tooling for Development Workflows https://css-tricks.com/star-apps-a-new-generation-of-front-end-tooling-for-development-workflows/ https://css-tricks.com/star-apps-a-new-generation-of-front-end-tooling-for-development-workflows/#comments Fri, 18 Jan 2019 17:41:45 +0000 http://css-tricks.com/?p=281419 Product teams from AirBnb and New York Times to Shopify and Artsy (among many others) are converging on a new set of best practices and technologies for building the web apps that their businesses depend on. This trend reflects core …


STAR Apps: A New Generation of Front-End Tooling for Development Workflows originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Product teams from AirBnb and New York Times to Shopify and Artsy (among many others) are converging on a new set of best practices and technologies for building the web apps that their businesses depend on. This trend reflects core principles and solve underlying problems that we may share, so it is worth digging deeper.

Some of that includes:

Naming things is hard, and our industry has struggled to name this new generation of tooling for web apps. The inimitable Orta Theroux calls it an Omakase; I slimmed it down and opted for a simpler backronym pulled from letters in the tooling outlined above: STAR (Design Systems, TypeScript, Apollo, and React).

STAR apps are not “yet another front-end stack.” They involve additional opinions and constraints. As such, STAR apps aren’t necessarily easy, either. They have a learning curve. A solo developer may find STAR apps unnecessarily verbose because they front-load communication overhead. STAR apps are more about product team workflow than they are about any specific technology.

However, we find that companies upon companies are finding this stack to be a worthwhile investment. We should ask why.

Context: From LAMP to MEAN

The LAMP stack was identified in 1998 by Michael Kunze to describe the combination of Linux, Apache, MySQL, and PHP as predominant open source technologies to write a full web server. In this model, all rendering and logic was done on the server side, and the role of JavaScript was extremely limited. To this day, this is the most common website architecture due to the popularity of long established frameworks like WordPress, which powers 30% of the Internet.

In the ensuing 20 years, the growth of the web platform (JavaScript in particular), led to a evolution of the “front end” discipline, as a complement to “back end” server-side concerns. Through a combination of Atwood’s Law and Metcalfe’s predictions on the triumph of the web over native platforms, these efforts culminated in a re-imagining of the monolithic architecture to straddle both front and back ends. One prominent encapsulation of this was the MEAN stack, coined by Val Karpov in 2013, to offer “full-stack” JavaScript alternatives, including MongoDB (for NoSQL data storage), Express and Node (to write web servers), and Angular (for writing reactive user interfaces).

What’s changed

However, in the last five years, multiple trends have chipped away at the MEAN stack and the ideal of the full-stack JavaScript monolith:

  • Instead of every developer writing bespoke endpoints, APIs have become an economy of their own with companies like Stripe, Twilio and Zapier growing purely through the strength of their APIs.
  • The acquisition of Firebase and launch of AWS Lambda in 2014 — and the subsequent serverless revolution — has made the concept of doing your own undifferentiated server management and reliability engineering far less appealing.
  • As for proprietary backends, it was clear that not all backend environments were going to be written in JavaScript, particularly with the continuing strength other language frameworks, including Rails, Laravel and .NET, and emerging languages like Go. Even the creators of Express.js and Node.js wound up abandoning JavaScript development altogether.

This has meant that the product engineer’s stack and primary work has shifted even more toward the front end over what was envisioned by the MEAN stack. Chris has described this as a phenomenon that gives extraordinary powers to front-end developers because of the trend toward front-end tooling for what’s traditionally been considered back-end territory. Front-end engineering has also evolved, mostly by incrementally adding a constraint layer on top of what we already use — adding a design philosophy, types, schemas, and component structure to how we make our apps.

Why all this change? Stop changing things!

The truth is that we now live in a world where product and business needs now have requirements to bring web app (including mobile web) engineering on par with Android, iOS, and desktop native app development, while our disparate web development tools are still woefully inadequate in comparison to those tightly scoped ecosystems. It’s not that there’s anything inherently wrong with older toolsets or that the new ones are perfect. Instead, the changes can be seen as responses to the underlying needs of product teams:

  • Stronger types: Type-checking isn’t a panacea, nor does it replace the need for tests, but it does enable better tooling and increase code confidence. TypeScript and GraphQL do this for clients and APIs, as Chris Toomey of thoughtbot has shown. Lauren Tan of Netflix has taken this idea even further to propose a full end-to-end Strongly Typed Graph.
  • Integrated designer/developer workflows: A reliance on manual code tests and design reviews doesn’t scale. Design systems now are comprehensive documentation on the how and why of reusable components across an organization. Brad Frost has shown how to set up “workshop” and “storefront” environments for a style guide and design system workflow using Gatsby. Design tools, like Sketch and Framer, have even begun to tightly integrate React and design into streamlined workflows. TypeScript and GraphQL both also offer tightly coupled self-documenting features with TSDoc, GraphiQL, and related IDE integrations.
  • Optimized for change: As product teams embrace iterative agile sprints and split testing, it is increasingly important to use flexible paradigms that embrace incremental adjustments. Dan Abramov of the React team calls this “second order” API design — robustness to changing requirements. Design Systems and React make it easy to compose reusable components at breakneck pace, with TypeScript dramatically shortening feedback loops. Adam Neary of Airbnb shows a wonderful example of refactoring and iterating with React and Apollo GraphQL in production.

Note that “product teams” in this article primarily refer to product engineering teams, though it is often the case that product design and product management are co-located or have heavy, frequent input. Engineering workflows must explicitly take them into account as a result.

Remaining frontiers

Believe it or not, I am being descriptive, rather than prescriptive; I’m not recommending that everybody throw out their code and start writing STAR apps. Rather, I am observing and calling out what I see as a trend where great product teams are all converging on this new pattern. And they just may be on to something.

However, I don’t believe the evolution has reached its conclusion. There are still too many important aspects of modern web app development that need broader consensus, which has resulted in a hodgepodge of custom or one-off solutions and checklists. A big one is performance. The average amount of JavaScript shipped on desktop and mobile has doubled in the last five years. All the wonderful web app engineering in the world will be for nothing if the user navigates away before it loads. The traditional solution has been (often hand-rolled) server-side rendering that’s later managed by frameworks like Next.js and After.js. However, this does still require running and managing a server, so static rendering solutions like Gatsby and React-Static have become popular to render apps straight to static markup to be lazily rehydrated later (the last piece of the JAMstack). Progressive Web App technology and patterns help make subsequent loads even faster and serve as a viable alternative to native experiences.

To be continued…

As this story continues to unfold, I believe that a lot more exploration and experimentation needs to happen to smooth the learning curve for more teams to adopt STAR app workflows. In fact, I am learning about it myself in the open at STAR Labs and invite you to tag along. If you have experiences to share or questions to ask, I am all ears.


STAR Apps: A New Generation of Front-End Tooling for Development Workflows originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/star-apps-a-new-generation-of-front-end-tooling-for-development-workflows/feed/ 8 281419
Why Do You Use Frameworks? https://css-tricks.com/why-do-you-use-frameworks/ https://css-tricks.com/why-do-you-use-frameworks/#comments Fri, 19 Oct 2018 17:30:34 +0000 http://css-tricks.com/?p=277597 Nicole Sullivan asked. People said:

  • 🐦… for the same reason that I buy ingredients rather than growing/raising all of my own food.
  • 🐦 I write too many bugs without them.
  • 🐦 Avoiding bikeshedding.
  • 🐦 … to solve problems


Why Do You Use Frameworks? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Nicole Sullivan asked. People said:

  • 🐦… for the same reason that I buy ingredients rather than growing/raising all of my own food.
  • 🐦 I write too many bugs without them.
  • 🐦 Avoiding bikeshedding.
  • 🐦 … to solve problems that are adjacent to, but distinct from, the problem I’m trying to solve at hand.
  • 🐦 Because to create the same functionality would require a much larger team
  • 🐦 I want to be able to focus on building the product rather than the tools.
  • 🐦 it’s easier to pick a framework and point to docs than teach and document your own solution.
  • 🐦 faster development
  • 🐦 They have typically solved the problems and in a better way than my first version or even fifth version will be.

There are tons more replies. Jeremy notes “exactly zero mention end users.” I said: Sometimes I just wanna be told what to do.

Nicole stubbed out the responses:

If you can’t get enough of the answers here, Rachel asked the same thing a few days later, this time scoped to CSS frameworks.


Why Do You Use Frameworks? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/why-do-you-use-frameworks/feed/ 5 277597
A Minimal JavaScript Setup https://css-tricks.com/a-minimal-javascript-setup/ https://css-tricks.com/a-minimal-javascript-setup/#comments Wed, 26 Sep 2018 13:44:20 +0000 http://css-tricks.com/?p=276737 Some people prefer to write JavaScript with React. For others, it’s Vue or jQuery. For others still, it is their own set of tools or a completely blank document. Some setups are minimal, some allow you to get things done …


A Minimal JavaScript Setup originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Some people prefer to write JavaScript with React. For others, it’s Vue or jQuery. For others still, it is their own set of tools or a completely blank document. Some setups are minimal, some allow you to get things done quickly, and some are crazy powerful, allowing you to build complex and maintainable applications. Every setup has advantages and disadvantages, but positives usually outweigh negatives when it comes to popular frameworks verified and vetted by an active community.

React and Vue are powerful JavaScript frameworks. Of course they are — that’s why both are trending so high in overall usage. But what is it that makes those, and other frameworks, so powerful? Is it the speed? Portability to other platforms like native desktop and mobile? Support of the huge community?

The success of a development team starts with an agreement. An agreement of how things are done. Without an agreement, code would get messy, and the software unsustainable quite quickly, even for relatively small projects. Therefore, a lot (if not most) of the power of a framework lies within this agreement. The ability to define conventions and common patterns that everyone adheres to. That idea is applicable to any framework, JavaScript or not. Those “rules” are essential to development and bring teams maintainability at any size, reusability of code, and the ability to share work with a community in a form anyone will understand. That’s why we can web search for some component/plugin that solves our problem rather than writing something on our own. We rely on open-source alternatives, no matter what framework we use.

Unfortunately, there are downsides to frameworks. As Adrian Holovaty (one of the Django creators) explains in his talk, frameworks tend to get bulky and bloated with features for one particular use case. It could be the inclusion of a really good idea. It could also be a desire to provide a one-size-fits-all solution for anyone and everyone’s needs. It could be to remain popular. Either way, there are downsides to frameworks in light of all the upsides they also have.

In server-rendered world, where we work with content that’s delivered to the browser from a server, this “framework mission” is filled with skills, ideas, and solutions that people share with co-workers, friends, and others. They tend to adopt consistent development rules and enforce them within their teams or companies, rather than relying on a predefined framework. For a long time, it’s been jQuery that has allowed people to share and reuse code on a global scale with its plugins — but that era is fading as new frameworks are entering the fold.

Let’s take a look at some core points that any framework — custom or not — ought to consider essential for encouraging a maintainable and reusable codebase.

Naming conventions

Some might say that naming is the hardest part of development. Whether it’s naming JavaScript variables, HTML classes, or any other number of things, a naming convention has a big impact on how we work together because it adds context and meaning to our code. A good example of a naming convention is BEM, a CSS methodology created by the folks at Yandex and adopted by many, many front-enders. That sort of standardization and consistency can help inform our objective, which is to have a standard convention for naming JavaScript selectors.

This situation might seem familiar: you revisit a project after a few months and you see some behavior happening on the page — maybe something you want to modify or fix. However, finding the source of that behavior can be a tricky thing. Is it the id attribute I should search for? Is it one of the classes? Maybe the data attribute for this particular element?

I think you get the point. What helps is having some kind of convention to simplify the process and make everyone work with the same names. And it doesn’t really matter if we’re going with classes (e.g. js-[name]) or data attributes (e.g. data-name="[name]"). All that matters is that the names conform to the same style. Surely enough, any framework you will meet will enforce a naming convention of some sort as well, whether it’s React, Vue, Bootstrap, Foundation, etc.

Scope

A developer will likely struggle with JavaScript scope at some point in time, but we are specifically focusing on DOM scope here. No matter what you do with JavaScript, you’re using it to affect some DOM element. Limiting parts of the code to a DOM element encourages maintainability and makes code more modular. Components in both React and Vue operate in a similar fashion, although their “component” concept is different than the standard DOM. Still, the idea scopes the code to a DOM element that is rendered by those components.

While we’re on the topic of DOM manipulation, referencing elements within the root element of the component is super helpful because it help avoids the constant need to select elements. React and Vue do this out of the box in a very good way.

Lifecycle

In the past, the page lifecycle was very straightforward: the browser loaded the page and the browser left the page. Creating or removing event listeners, or making code run at the right time was much simpler, as you would simply create everything you need on load, and rarely bother with disabling your code, since the browser would do it for you by default.

Nowadays, the lifecycle tends to be much more dynamic, thanks to state management and the way we prefer to manipulate changes directly to the DOM or load the contents of pages with JavaScript. Unfortunately, that usually brings some issues where you may need to re-run parts of your code at certain times.

I can’t tell how many times in my life I’ve had to play around with code to get my event handlers to run correctly after re-writing part of the DOM. Sometimes it is possible to solve this with event delegation. Other times, your code handlers don’t run at all or run several times because they are suddenly attached twice.

Another use case would be the need to create an instance of libraries after changing the DOM, like “fake selects.”

In any case, the lifecycle is important and limiting your code to a DOM element certainly helps here as well, since you know that the code applied to that element needs to be re-run in case the element is re-rendered.

Frameworks do the same with functions as componentDidMount or componentDidUpdate, which give you an easy way of running code exactly when you need it.

Reusability

Copying code from somewhere else and reusing it is super common. Who hasn’t used a snippet from a past project or an answer from StackOverflow, right? People even invented services like npm meant for one thing: to easily share and reuse code. There is no need to reinvent the wheel and sharing code with others is something that is convenient, handy, and often more efficient than spinning something up from scratch.

Components, whether it’s React, Vue, or any other building block of a framework encourage reusability by having a wrapper around a piece of code that serves some specific purpose. A standardized wrapper with an enforced format. I would say this is more of a side effect of having some base we can build on, than an intentional effort for reusability, as any base will always need some standard format of a code it can run, the same way programming languages have a syntax we need to follow… but it is a super convenient and useful side effect, for sure. By combining this gained reusability with package managers like Yarn, and bundlers like webpack, we can suddenly make code written by many developers around the world work together in our app with almost no effort.

While not all code is open-source and shareable, a common structure will help folks in smaller teams as well, so anyone is able to understand most of the code written within the team without having to consult its author.

DOM manipulation with performance in mind

Reading and writing to the DOM is costly. Developers of front-end frameworks keep that in mind and try to optimize as much as possible with states, virtual DOM and other methods to make changes to the DOM when it’s needed and where it’s needed… and so should we. While we’re more concerned with server-rendered HTML, most of the code ends up reading or writing to the DOM. After all, that’s what JavaScript is for.

While most of the changes of the DOM are minimal, they can also occur quite often. A nice example of frequent reading/writing is executing a script on page scroll. Ideally, we would like to avoid adding classes, attributes or changing the contents of elements directly in the handler, even if we write the same classes, attributes or contents because our changes still get processed by the browser and are still expensive, even when nothing changes for the user.

Size

Last, but not least: size. Size is critical or at least should be for a framework. The code discussed in this article is meant to be used as a base across many projects. It should be as small as possible and avoid any unnecessary code that could be added manually for one-off use cases. Ideally, it should be modular so that we can pull pieces of it out à la carte, based on the specific needs for the project at hand.

While the size of self-written code is usually reasonable, many projects end up having at least some dependencies/libraries to fill in gaps, and those can make things quite bulky really fast. Let’s say we have a carousel on a top-level page of a site and some charts somewhere deeper. We can turn to existing libraries that would handle these things for us, like slick carousel (10 KB minified/gzipped, excluding jQuery) and highcharts (73 KB minified/gzipped). That’s over 80 KB of code and I’d bet that not every byte is needed for our project. As Addy Osmani explains, JavaScript is expensive and its size is not the same as other assets on a page. It’s worth keeping that in mind the next time you find yourself reaching for a library, though it shouldn’t discourage you from doing it if the positives outweigh the negatives.

A look at a minimal solution we call Gia

Let’s take a look at something I’ve been working on and using for a while with my team at Giant. We like JavaScript and we want to work directly with JavaScript rather than a framework. But at the same time, we need the maintainability and reusability that frameworks offer. We tried to take some concepts from popular frameworks and apply them to a server-rendered website where the options for a JavaScript setup are so wide, and yet so limited.

We’ll go through some basic features of our setup and focus on how it solves the points we’ve covered so far. Note that many of the solutions to our needs are directly inspired by big frameworks, so if you see some similarities, know that it’s not an accident. We call it Gia (get it, like short for Giant?!) and you can get it from npm and find the source code on GitHub.

Gia, like many frameworks, is built around components that give you a basic building block and some advantages we’ll touch on in a bit. But don’t confuse Gia components with the component concepts used by React and Vue, where all your HTML is a product of the component. This is different.

In Gia, a component is a wrapper for your own code that runs in the scope of a DOM element, and the instance of a component is stored within the element itself. As a result, an instance is automatically removed from the memory by the garbage collector in case the element is removed from the DOM. The source code of the component can be found here and is fairly simple.

Apart from a component, Gia includes several helpers to apply, destroy and work with the component instance or communicate between components (with standard eventbus included for convenience).

Let’s start with a basic setup. Gia is using an attribute to select elements, along with the name of the component to be executed (i.e. g-component="[component name]"). This enforces a consistent naming convention. Running the loadComponents function creates the instances defined with the g-component attribute.

See the Pen Basic component by Georgy Marchuk (@gmrchk) on CodePen.

Gia components also allow us to easily select elements within the root element with the g-ref attribute. All that needs to be done is to define the refs that are expected and whether we’re working with a single element or an array of them. Reference is then accessible in the this.ref object within the component.

See the Pen Component with ref elements by Georgy Marchuk (@gmrchk) on CodePen.

As a bonus, default options can be defined in the component, which are automatically rewritten by any options included in g-options attribute.

See the Pen Component with options by Georgy Marchuk (@gmrchk) on CodePen.

The component includes methods that are executed at different times, in order to solve the lifecycle issue. Here’s an example that shows how a component can be initialized or removed:

See the Pen load/remove components by Georgy Marchuk (@gmrchk) on CodePen.

Notice how loadComponents function doesn’t apply the same component when it already exists.

It is not necessary to remove listeners attached to the root element of a component or elements within it before re-rendering them since the elements would be removed from the DOM anyway. However, there can be some listeners created on global objects (e.g. window), like the ones used for scroll handling. In this case, it is necessary to remove the listener manually before destroying the component instance in order to avoid memory leaks.

The concept of a component scoped to a DOM element is similar in its nature to React and Vue components, but with a key exception that the DOM structure is outside of the component. As a result, we have to make sure it fits the component. Defining the ref elements certainly helps, as Gia component will tell you when the required refs are not present. That makes the component reusable. The following is example implementation of a basic carousel that could be easily reused or shared:

See the Pen Basic carousel component by Georgy Marchuk (@gmrchk) on CodePen.

While we’re talking about reusability, it’s important to mention that components don’t have to be reused in their existing state. In other words, we can extend them to create new components as any other JavaScript class. That means we can prepare a general component and build upon it.

To give an example, a component that would give us the distance between the cursor and the center of an element seems like a thing that could be useful someday. Such a component can be found here. After having that ready, it’s ridiculously easy to build upon it and work with provided numbers, as the next example shows in the render function, although we could argue about the usefulness of this particular example.

See the Pen ZMXMJo by Georgy Marchuk (@gmrchk) on CodePen.

Let’s try to look into optimized DOM manipulations. Detecting if a change to the DOM is supposed to happen can be manually stored or checked without directly accessing the DOM, but that tends to be a lot of work which we might want to avoid.

This is where Gia really drew inspiration from React, with simple, stripped down component state management. The state of a component is set similarly to states in React, using a setState function.

That said, there is no rendering involved in our component. The content is rendered by the server, so we need to make a use of the changes in state elsewhere. The state changes are evaluated and any actual changes are sent to the stateChange method of a component. Ideally, any interaction between the component and the DOM would be handled in this function. In case some part of the state doesn’t change, it won’t be present in the stateChanges object passed into a function and therefore won’t be processed — the DOM won’t be touched without it being truly necessary.

Check the following example with a component showing sections that are visible in the viewport:

See the Pen Sections in viewport component by Georgy Marchuk (@gmrchk) on CodePen.

Notice how writing to the DOM (visualized by the blink) is only done for items where the state actually changes.

Now we are getting to my favorite part! Gia is truly minimal. The entire bundle containing all the code, including all the helpers, takes up a measly 2.68 KB (minified/gzipped). Not to mention that you most likely won’t need all of Gia’s parts and would end up importing even less with a bundler.

As mentioned earlier, the size of the code can rapidly increase by including third-party dependencies. That’s why Gia also includes code splitting support where you can define a dependency for a component, which will only be loaded when the component is being initialized for the first time, without any additional setup required to the bundler. That way, the bulky libraries used somewhere deep within your site or application don’t have to slow things down.

In case you decide one day that you really want to take advantage of all the goodies big frameworks can offer somewhere in your code, there is nothing easier than just loading it like any other dependency for the component.

class SampleComponent extends Component {
  async require() {
    this.vue = await import('vue');
  }

  mount() {
    new this.vue({
      el: this.element,
    });
  }
}

Conclusion

I guess the main point of this article is that you don’t need a framework to write maintainable and reusable code. Following and enforcing a few concepts (that frameworks use as well) can take you far on its own. While Gia is minimal and does not have many of the robust features offered by big players, like React and Vue, it still helps us get that clean structure that is so important in the long term. It includes some more interesting stuff that didn’t make the cut here. If you like it so far, go check it out!

GitHub Repo

There are lots and lots of use cases, and different needs require different approaches. Various frameworks can do plenty of the work for you; in other cases, they may be constraining.

What is your minimal setup and how do you account for the points we covered here? Do you prefer a framework or non-framework environment? Do you use frameworks in combination with static site generators like Gatsby? Let me know!


A Minimal JavaScript Setup originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/a-minimal-javascript-setup/feed/ 4 276737
The “Developer Experience” Bait-and-Switch https://css-tricks.com/the-developer-experience-bait-and-switch/ Wed, 26 Sep 2018 13:43:41 +0000 http://css-tricks.com/?p=276827 Alex Russell describes his thoughts on the current state of JavaScript and how we might sometimes put a ton of focus on the ease-of-use of development at the expense of user experience. So, for example, we might pick a massive …


The “Developer Experience” Bait-and-Switch originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Alex Russell describes his thoughts on the current state of JavaScript and how we might sometimes put a ton of focus on the ease-of-use of development at the expense of user experience. So, for example, we might pick a massive framework to make development easier and faster but then that might have an enormous impact on the user.

Alex describes it as substituting “developer value for user value.”

The “developer experience” bait-and-switch works by appealing to the listener’s parochial interests as developers or managers, claiming supremacy in one category in order to remove others from the conversation. The swap is executed by implying that by making things better for developers, users will eventually benefit equivalently. The unstated agreement is that developers share all of the same goals with the same intensity as end users and even managers. This is not true.

Here’s the kicker, though:

JavaScript is the web’s CO2. We need some of it, but too much puts the entire ecosystem at risk. Those who emit the most are furthest from suffering the consequences — until the ecosystem collapses. The web will not succeed in the markets and form-factors where computing is headed unless we get JS emissions under control.

By that standard, it could also stand to reason that the work we put into “design systems” falls into this trap. But there is something to be said about achieving ease of use on this front: a more consistent codebase is probably a very good thing for accessibility, UX consistency, etc. etc.

So, although I agree with Alex’s premise here, I’m not entirely sure I agree wholeheartedly on this subject.

To Shared LinkPermalink on CSS-Tricks


The “Developer Experience” Bait-and-Switch originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
276827