The Great Divide

Let’s say there is a divide happening in front-end development. I feel it, but it’s not just in my bones. Based on an awful lot of written developer sentiment, interviews Dave Rupert and I have done on ShopTalk, and in-person discussion, it’s, as they say… a thing.

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 skill sets are heavily revolved around JavaScript.

On the other, an army of developers whose interests, responsibilities, and skill sets are focused on other areas of the front end, like HTML, CSS, design, interaction, patterns, accessibility, etc.

Let’s hear from people who are feeling this divide.

In response to our post, “What makes a good front-end developer?”, Steven Davis wrote:

I think we need to move away from the term myself. We should split into UX Engineers and JavaScript Engineers. They are different mindsets. Most people are not amazing at both JavaScript and CSS. Let UX Engineers work closely with UX/Design to create great designs, interactions, prototypes, etc. and let JavaScript Engineers handle all the data parts.

So sick of being great at CSS but being forced into JavaScript. I’m not a programmer!

This schism isn’t happening under our feet. We’re asking for it.

I heard it called an identity crisis for the first time in Vernon Joyce’s article, “Is front-end development having an identity crisis?” He points to the major JavaScript frameworks:

Frameworks like Angular or libraries like React require developers to have a much deeper understanding of programming concepts; concepts that might have historically been associated only with the back end. MVC, functional programming, higher-order functions, hoisting… hard concepts to grasp if your background is in HTML, CSS, and basic interactive JavaScript.

This rings true for me. I enjoy working with and reading about modern frameworks, fancy build tools, and interesting data layer strategies. Right now, I’m enjoying working with React as a UI library, Apollo GraphQL for data, Cypress for integration testing, and webpack as a build tool. I am constantly eying up CSS-in-JS libraries. Yet, while I do consider those things a part of front-end development, they feel cosmically far away from the articles and conversations around accessibility, semantic markup, CSS possibilities, UX considerations, and UI polish, among others. It feels like two different worlds.

When companies post job openings for “Front-End Developer,” what are they really asking for? Assuming they actually know (lolz), the title front-end developer alone isn’t doing enough. It’s likely more helpful to know which side of the divide they need the most.

Who gets the job? Who’s right for the job? Is the pay grade the same for these skill sets?

My hope is that the solution is writing more descriptive job postings. If clearly defined and agreed upon job titles are too much of an ask for the industry at large (and I fear that it is), we can still use our words. Corey Ginnivan put it well:

I’d love more job descriptions to be more vulnerable and open — let people know what you want to achieve, specify what they’ll be working on, but open it as a growth opportunity for both parties.

Job posting for a Front-End Developer that describes the role.
This seemed to work pretty well for us at CodePen. Our own Cassidy Williams said she really appreciated this writeup when Rachel Smith sent it to her to consider.

“Front-end developer” is still a useful term. Like Mina Markham described to us recently, it’s who people that primarily work with browsers and people using those browsers are. But it’s a generic shorthand, says Miriam Suzanne:

Front-end developer is shorthand for when the details don’t matter. Like being in an indie-rock band — who knows what that is, but I say it all the time. Shorthand is great until you’re posting a job description. When the details matter, we already have more detailed language — we just have to use it.

To put a point on this divide a bit more, consider this article by Trey Huffine, “A Recap of Frontend Development in 2018.” It’s very well done! It points to big moments this year, shows interesting data, and makes predictions about what we might see next year. But it’s entirely based around the JavaScript ecosystem. HTML is only mentioned in the context of JavaScript-powered static site generators and CSS is only mentioned in the context of CSS-in-JS. It’s front-end development, but perhaps one half of it: the JavaScript half. If you read that summary and don’t connect with much in there, then my advice would be:

That’s OK. You can still be a front-end developer. 🙏

You might be exploring layout possibilities, architecting a CSS or design system, getting deep into UX, building interesting animations, digging into accessibility, or any other number of firmly front-end development jobs. There’s more than enough to go around.

Remember just last last year how Frank Chimero, who builds incredibly great websites for himself and clients, was totally bewildered with where front-end development had gone? To summarize:

… other people’s toolchains are absolutely inscrutable from the outside. Even getting started is touchy. Last month, I had to install a package manager to install a package manager. That’s when I closed my laptop and slowly backed away from it. We’re a long way from the CSS Zen Garden where I started.

A long way indeed. I might argue that you don’t have to care. If you’ve been and continue to be successful building websites any way you know how for yourself and clients, hallelujah! Consider all this new toolchain stuff entirely as an opt-in deal that solves different problems than you have.

And yet, this toolchain opaqueness prods at even the people necessarily embedded in it. Dave Rupert documents a real bug with a solution buried so deep that it’s a miracle it was rooted out. Then he laments:

As toolchains grow and become more complex, unless you are expertly familiar with them, it’s very unclear what transformations are happening in our code. Tracking the differences between the input and output and the processes that code underwent can be overwhelming.

Who needs these big toolchains? Generally, it’s the big sites. It’s a bit tricky to pin down what big means, but I bet you have a good feel for it. Ironically, while heaps of tooling add complexity, the reason they are used is for battling complexity. Sometimes it feels like releasing cougars into the forest to handle your snake problem. Now you have a cougar problem.

The most visible discussions around all of this are dominated by people at the companies that are working on these big and complex sites. Bastian Allgeier wrote:

Big team needs “x” that’s why “x” is the best solution for everyone. I think this is highly toxic for smaller teams with different requirements and definitions of what’s “maintainable” or “sustainable”. I get in touch with a lot of smaller agencies and freelancers from all over the world and it’s interesting how their work is often completely detached from the web’s VIP circus.

What is going on here? What happened? Where did this divide come from? The answer is pretty clear to me:

JavaScript dun got big.

So big:

  • It’s everywhere on the front end of websites. The major JavaScript front-end frameworks are seeing explosive growth and dominating job postings. These frameworks are used by loads of teams to power loads of websites. Native JavaScript is evolving quickly as well, which has lots of people excited.
  • It powers backends, too. Your site might be powered by or involve a Node.js server. Your build process is likely to be powered by JavaScript.
  • Third-party JavaScript powers so many front-end features, from a site’s ad network and analytics to full-blown features like reviews, comments, and related content.
  • Concepts like Node-powered cloud functions, storage, and authentication, combined with low-cost and low-effort scalable hosting, have empowered the crap out of JavaScript-focused front-end developers. They can use their skills exclusively to ship entire functional products.

A front-end developer with a strong JavaScript skill set is wildly empowered these days. I’ve been calling it the all-powerful front-end developer, and I did a whole talk on it:

Through all the possibilities that swirl around the idea of serverless combined with prepackaged UI frameworks, a front-end developer can build just about anything without needing much, if any, help from other disciplines. I find that exciting and enticing, but also worthy of pause. It’s certainly possible that you become so framework-driven going down this path that your wider problem-solving skills suffer. I heard that sentiment from Estelle Weyl who goes so far as to say she thinks of developers more as “framework implementers,” reserving the title of engineer for tool-agnostic problem solvers.

This front-end empowerment is very real. Particularly in the last few years, front-end developers have gotten especially powerful. So powerful that Michael Scharnagl says he’s seen companies shift their hiring in that direction:

What I am seeing is that many developers focus entirely on JavaScript nowadays and I see companies where they replace back-end developers with JavaScript developers.

What some don’t understand is that a JavaScript developer is not per se a front-end developer. A JavaScript developer may not like to write CSS or care about semantics. That’s the same way I prefer not to work directly with databases or configure a server. That’s okay. What is not okay is if you don’t want to use something and at the same time tell others what they do is easy or useless. Even worse is if you try to tell experts in their field that they are doing it all wrong and that they should do it your way.

And Jay Freestone takes a stab at why:

Over the last few years, we’ve started to see a significant shift in the role of the front-end developer. As applications have become increasingly JavaScript-heavy there has been a necessity for front-end engineers to understand and practice architectural principles that were traditionally in the domain of back-end developers, such as API design and data modeling.

It’s happened even with my own small scale work. We were looking for a back-end Go developer to help evolve our web services at CodePen. When we didn’t have a lot of luck finding the perfect person, we decided to go another direction. We saw that our stack was evolving into something that’s extremely welcoming to JavaScript-focused front-end developers to the point where we could easily put more of them to work right away. So that’s what we did.

There may be a cyclical nature to some of this as well. We’re seeing coding schools absolutely explode and produce fairly talented developers in less than a year. These code school graduates are filling labor gaps, but more importantly, as Brad Westfall tells me, starting to lead industry discussions rather than be passive followers of them. And make no mistake: these schools are producing developers on the JavaScript side of the divide. Every single code school web development curriculum I’ve ever seen treats HTML/CSS/UI/UX/A11Y topics as early fundamentals that students breeze through or they are sprinkled in as asides while JavaScript dominates the later curriculum. Can you come in and teach our students all the layout concepts in three hours?

When JavaScript dominates the conversations around the front end, it leads to some developers feeling inadequate. In a comment on Robin Rendle’s “Front-end development is not a problem to be solved,” Nils writes:

Maybe the term front-end developer needs some rethinking. When I started working, front-end was mostly HTML, CSS, and some JavaScript. A good front-end developer needed to be able to translate a Photoshop layout to a pixel perfect website. Front end today is much much more. If you want to learn front-end development, people seem to start learning git, npm, angular, react, vue and all of this is called front-end development.

I am a designer and I think I’m pretty good at HTML and CSS, but that’s not enough anymore to be a front-end developer.

Robin himself gave himself the job title, Adult Boy That Cares Too Much About Accessibility and CSS and Component Design but Doesn’t Care One Bit About GraphQL or Rails or Redux but I Feel Really Bad About Not Caring About This Other Stuff Though.

It’s also frustrating to people in other ways. Remember Lara Schenk’s story of going in for a job interview? She met 90% of the listed qualifications, only to have the interview involve JavaScript algorithms. She ultimately didn’t get the job because of that. Not everybody needs to get every job they interview for, but the issue here is that front-end developer isn’t communicating what it needs to as an effective job title.

It feels like an alternate universe some days.

Two “front-end web developers” can be standing right next to each other and have little, if any, skill sets in common. That’s downright bizarre to me for a job title so specific and ubiquitous. I’m sure that’s already the case with a job title like designer, but front-end web developer is a niche within a niche already.

Jina Bolton is a front-end developer and designer I admire. Yet, in a panel discussion I was on with her a few years ago, she admits she doesn’t think of herself with that title:

When I was at Apple, my job title when I first started out there was front-end developer. Would I call myself that now? No, because it’s become such a different thing. Like, I learned HTML/CSS, I never learned JavaScript but I knew enough to work around it. Now—we’re talking about job titles—when I hear “front-end developer,” I’m going to assume you know a lot more than me.

It seems like, at the time, that lack of a JavaScript focus made Jina feel like she’s less skilled than someone who has the official title of front-end developer. I think people would be lucky to have the skills that Jina has in her left pinky finger, but hey that’s me. Speaking to Jina recently, she says she still avoids the title specifically because it leads to incorrect assumptions about her skill set.

Mandy Michael put a point on this better than anyone in her article, Is there any value in people who cannot write JavaScript?”:

What I don’t understand is why it’s okay if you can “just write JS”, but somehow you’re not good enough if you “just write HTML and CSS”.

When every new website on the internet has perfect, semantic, accessible HTML and exceptionally executed, accessible CSS that works on every device and browser, then you can tell me that these languages are not valuable on their own. Until then we need to stop devaluing CSS and HTML.

Mandy uses her post for peacemaking. She’s telling us, yes, there is a divide, but no, neither side is any more valuable than the other.

Another source of frustration is when the great divide leads to poor craftsmanship. This is what I see as the cause of most of the jeering and poking that occurs across aisles. Brad Frost points to the term “full-stack developer” as a little misleading:

In my experience, “full-stack developers” always translates to “programmers who can do front-end code because they have to and it’s ‘easy’.” It’s never the other way around. The term “full-stack developer” implies that a developer is equally adept at both frontend code and backend code, but I’ve never in my personal experience witnessed anyone who truly fits that description.

Heydon Pickering says something similar. When you’re hired at this mythical high level, something like HTML is unlikely to be a strong suit.

… one of the most glaring issues with making Full Stack Developers the gatekeepers of all-things-code is the pitiful quality of the HTML output. Most come from a computer science background, and document structure is simply not taught alongside control structure. It’s not their competency, but we still make it their job.

Just like it may not be my job to configure our deployment pipeline and handle our database scaling (I’d do a terrible job if that task fell to me), perhaps it’s best to leave the job of HTML and CSS to do those who do it well. Maybe it’s easier to say: Even if there is a divide, that doesn’t absolve any of us from doing a good job.

Just as architecture and developer ergonomics are all our jobs, we should view performance, accessibility, and user experience among our line of work. If we can’t do a good job with any particular part of it, make sure there’s someone else who can do that part. Nobody is allowed to do a bad job.

It’s worth mentioning that there are plenty of developers with skill sets that cross the divide and do so gracefully. I think of our own Sarah Drasner who is known as an incredible animator, SVG expert, and a core team member of Vue who also works at Microsoft on Azure. Full stack, indeed.

I expand upon a lot of these topics in another recent conference talk I gave at WordCamp US:

Is there any solution to these problems of suffering craftsmanship and skill devaluation? Are the problems systemic and deeply rooted, or are they surface level and without severe consequence? Is the divide real, or a temporary rift? Is the friction settling down or heating up? Will the front-end developer skill set widen or narrow as the years pass? Let’s keep talking about this!

Even as JavaScript continues heating up, Rachel Andrew tells me it used to be hard to fill a CSS workshop, but these days conference organizers are asking for them as they are in hot demand. One thing is certain, like ol’ Heraclitus likes to say, the only constant is change.


The post The Great Divide appeared first on CSS-Tricks.

Introducing The Component-Based API

Introducing The Component-Based API

Introducing The Component-Based API

Leonardo Losoviz

An API is the communication channel for an application to load data from the server. In the world of APIs, REST has been the more established methodology, but has lately been overshadowed by GraphQL, which offers important advantages over REST. Whereas REST requires multiple HTTP requests to fetch a set of data to render a component, GraphQL can query and retrieve such data in a single request, and the response will be exactly what is required, without over or under-fetching data as typically happens in REST.

In this article, I will describe another way of fetching data which I have designed and called “PoP” (and open sourced here), which expands on the idea of fetching data for several entities in a single request introduced by GraphQL and takes it a step further, i.e. while REST fetches the data for one resource, and GraphQL fetches the data for all resources in one component, the component-based API can fetch the data for all resources from all components in one page.

Using a component-based API makes most sense when the website is itself built using components, i.e. when the webpage is iteratively composed of components wrapping other components until, at the very top, we obtain a single component that represents the page. For instance, the webpage shown in the image below is built with components, which are outlined with squares:

Screenshot of a component-based webpage
The page is a component wrapping components wrapping components, as shown by the squares. (Large preview)

A component-based API is able to make a single request to the server by requesting the data for all of the resources in each component (as well as for all of the components in the page) which is accomplished by keeping the relationships among components in the API structure itself.

Among others, this structure offers the following several benefits:

  • A page with many components will trigger only one request instead of many;
  • Data shared across components can be fetched only once from the DB and printed only once in the response;
  • It can greatly reduce — even completely remove — the need for a data store.

We will explore these in details throughout the article, but first, let’s explore what components actually are and how we can build a site based on such components, and finally, explore how a component-based API works.

Recommended reading: A GraphQL Primer: Why We Need A New Kind Of API

Building A Site Through Components

A component is simply a set of pieces of HTML, JavaScript and CSS code put all together to create an autonomous entity. This can then wrap other components to create more complex structures, and be itself wrapped by other components, too. A component has a purpose, which can range from something very basic (such as a link or a button) to something very elaborate (such as a carousel or a drag-and-drop image uploader). Components are most useful when they are generic and enable customization through injected properties (or “props”), so that they can serve a wide array of use cases. In the utmost case, the site itself becomes a component.

The term “component” is often used to refer both to functionality and design. For instance, concerning functionality, JavaScript frameworks such as React or Vue allow to create client-side components, which are able to self-render (for instance, after the API fetches their required data), and use props to set configuration values on their wrapped components, enabling code reusability. Concerning design, Bootstrap has standardized how websites look and feel through its front-end component library, and it has become a healthy trend for teams to create design systems to maintain their websites, which allows the different team members (designers and developers, but also marketers and salesmen) to speak a unified language and express a consistent identity.

Componentizing a site then is a very sensible way to make the website become more maintainable. Sites using JavaScript frameworks such as React and Vue are already component-based (at least on the client-side). Using a component library like Bootstrap doesn’t necessarily make the site be component-based (it could be a big blob of HTML), however, it incorporates the concept of reusable elements for the user interface.

If the site is a big blob of HTML, for us to componentize it we must break the layout into a series of recurring patterns, for which we must identify and catalogue sections on the page based on their similarity of functionality and styles, and break these sections down into layers, as granular as possible, attempting to have each layer be focused on a single goal or action, and also trying to match common layers across different sections.

Note: Brad Frost’s “Atomic Design” is a great methodology for identifying these common patterns and building a reusable design system.

Identifying elements to componentize a webpage
Brad Frost identifies five distinct levels in atomic design for creating design systems. (Large preview)

Hence, building a site through components is akin to playing with LEGO. Each component is either an atomic functionality, a composition of other components, or a combination of the two.

As shown below, a basic component (an avatar) is iteratively composed by other components until obtaining the webpage at the top:

Sequence of components produced, from an avatar all the way up to the webpage. (Large preview)

The Component-Based API Specification

For the component-based API I have designed, a component is called a “module”, so from now on the terms “component” and “module” are used interchangeably.

The relationship of all modules wrapping each other, from the top-most module all the way down to the last level, is called the “component hierarchy”. This relationship can be expressed through an associative array (an array of key => property) on the server-side, in which each module states its name as the key attribute and its inner modules under the property modules. The API then simply encodes this array as a JSON object for consumption:

// Component hierarchy on server-side, e.g. through PHP:
[ "top-module" => [ "modules" => [ "module-level1" => [ "modules" => [ "module-level11" => [ "modules" => [...] ], "module-level12" => [ "modules" => [ "module-level121" => [ "modules" => [...] ] ] ] ] ], "module-level2" => [ "modules" => [ "module-level21" => [ "modules" => [...] ] ] ] ] ]
] // Component hierarchy encoded as JSON:
{ "top-module": { modules: { "module-level1": { modules: { "module-level11": { ... }, "module-level12": { modules: { "module-level121": { ... } } } } }, "module-level2": { modules: { "module-level21": { ... } } } } }

The relationship among modules is defined on a strictly top-down fashion: a module wraps other modules and knows who they are, but it doesn’t know — and doesn’t care — which modules are wrapping him.

For instance, in the JSON code above, module module-level1 knows it wraps modules module-level11 and module-level12, and, transitively, it also knows it wraps module-level121; but module module-level11 doesn’t care who is wrapping it, consequently is unaware of module-level1.

Having the component-based structure, we can now add the actual information required by each module, which is categorized into either settings (such as configuration values and other properties) and data (such as the IDs of the queried database objects and other properties), and placed accordingly under entries modulesettings and moduledata:

{ modulesettings: { "top-module": { configuration: {...}, ..., modules: { "module-level1": { configuration: {...}, ..., modules: { "module-level11": { repeat... }, "module-level12": { configuration: {...}, ..., modules: { "module-level121": { repeat... } } } } }, "module-level2": { configuration: {...}, ..., modules: { "module-level21": { repeat... } } } } } }, moduledata: { "top-module": { dbobjectids: [...], ..., modules: { "module-level1": { dbobjectids: [...], ..., modules: { "module-level11": { repeat... }, "module-level12": { dbobjectids: [...], ..., modules: { "module-level121": { repeat... } } } } }, "module-level2": { dbobjectids: [...], ..., modules: { "module-level21": { repeat... } } } } } }

Following, the API will add the database object data. This information is not placed under each module, but under a shared section called databases, to avoid duplicating information when two or more different modules fetch the same objects from the database.

In addition, the API represents the database object data in a relational manner, to avoid duplicating information when two or more different database objects are related to a common object (such as two posts having the same author). In other words, database object data is normalized.

Recommended reading: Building A Serverless Contact Form For Your Static Site

The structure is a dictionary, organized under each object type first and object ID second, from which we can obtain the object properties:

{ databases: { primary: { dbobject_type: { dbobject_id: { property: ..., ... }, ... }, ... } }

This JSON object is already the response from the component-based API. Its format is a specification all by itself: As long as the server returns the JSON response in its required format, the client can consume the API independently of how it is implemented. Hence, the API can be implemented on any language (which is one of the beauties of GraphQL: being a specification and not an actual implementation has enabled it to become available in a myriad of languages.)

Note: In an upcoming article, I will describe my implementation of the component-based API in PHP (which is the one available in the repo).

API response example

For instance, the API response below contains a component hierarchy with two modules, page => post-feed, where module post-feed fetches blog posts. Please notice the following:

  • Each module knows which are its queried objects from property dbobjectids (IDs 4 and 9 for the blog posts)
  • Each module knows the object type for its queried objects from property dbkeys (each post’s data is found under posts, and the post’s author data, corresponding to the author with the ID given under the post’s property author, is found under users)
  • Because the database object data is relational, property author contains the ID to the author object instead of printing the author data directly.
{ moduledata: { "page": { modules: { "post-feed": { dbobjectids: [4, 9] } } } }, modulesettings: { "page": { modules: { "post-feed": { dbkeys: { id: "posts", author: "users" } } } } }, databases: { primary: { posts: { 4: { title: "Hello World!", author: 7 }, 9: { title: "Everything fine?", author: 7 } }, users: { 7: { name: "Leo" } } } }

Differences Fetching Data From Resource-Based, Schema-Based And Component-Based APIs

Let’s see how a component-based API such as PoP compares, when fetching data, to a resource-based API such as REST, and to a schema-based API such as GraphQL.

Let’s say IMDB has a page with two components which need to fetch data: “Featured director” (showing a description of George Lucas and a list of his films) and “Films recommended for you” (showing films such as Star Wars: Episode I — The Phantom Menace and The Terminator). It could look like this:

Next-generation IMDB
Components ‘Featured director’ and ‘Films recommended for you’ for the next-generation IMDB site. (Large preview)

Let’s see how many requests are needed to fetch the data through each API method. For this example, the “Featured director” component brings one result (“George Lucas”), from which it retrieves two films (Star Wars: Episode I — The Phantom Menace and Star Wars: Episode II — Attack of the Clones), and for each film two actors (“Ewan McGregor” and “Natalie Portman” for the first film, and “Natalie Portman” and “Hayden Christensen” for the second film). The component “Films recommended for you” brings two results (Star Wars: Episode I — The Phantom Menace and The Terminator), and then fetches their directors (“George Lucas” and “James Cameron” respectively).

Using REST to render component featured-director, we may need the following 7 requests (this number can vary depending on how much data is provided by each endpoint, i.e. how much over-fetching has been implemented):

GET - /featured-director
GET - /directors/george-lucas
GET - /films/the-phantom-menace
GET - /films/attack-of-the-clones
GET - /actors/ewan-mcgregor
GET - /actors/natalie-portman
GET - /actors/hayden-christensen

GraphQL allows, through strongly typed schemas, to fetch all the required data in one single request per component. The query to fetch data through GraphQL for the component featuredDirector looks like this (after we have implemented the corresponding schema):

query { featuredDirector { name country avatar films { title thumbnail actors { name avatar } } }

And it produces the following response:

{ data: { featuredDirector: { name: "George Lucas", country: "USA", avatar: "...", films: [ { title: "Star Wars: Episode I - The Phantom Menace", thumbnail: "...", actors: [ { name: "Ewan McGregor", avatar: "...", }, { name: "Natalie Portman", avatar: "...", } ] }, { title: "Star Wars: Episode II - Attack of the Clones", thumbnail: "...", actors: [ { name: "Natalie Portman", avatar: "...", }, { name: "Hayden Christensen", avatar: "...", } ] } ] } }

And querying for component “Films recommended for you” produces the following response:

{ data: { films: [ { title: "Star Wars: Episode I - The Phantom Menace", thumbnail: "...", director: { name: "George Lucas", avatar: "...", } }, { title: "The Terminator", thumbnail: "...", director: { name: "James Cameron", avatar: "...", } } ] }

PoP will issue only one request to fetch all the data for all components in the page, and normalize the results. The endpoint to be called is simply the same as the URL for which we need to get the data, just adding an additional parameter output=json to indicate to bring the data in JSON format instead of printing it as HTML:

GET - /url-of-the-page/?output=json

Assuming that the module structure has a top module named page containing modules featured-director and films-recommended-for-you, and these also have submodules, like this:

"page" modules "featured-director" modules "director-films" modules "film-actors" "films-recommended-for-you" modules "film-director"

The single returned JSON response will look like this:

{ modulesettings: { "page": { modules: { "featured-director": { dbkeys: { id: "people", }, modules: { "director-films": { dbkeys: { films: "films" }, modules: { "film-actors": { dbkeys: { actors: "people" }, } } } } }, "films-recommended-for-you": { dbkeys: { id: "films", }, modules: { "film-director": { dbkeys: { director: "people" }, } } } } } }, moduledata: { "page": { modules: { "featured-director": { dbobjectids: [1] }, "films-recommended-for-you": { dbobjectids: [1, 3] } } } }, databases: { primary: { people { 1: { name: "George Lucas", country: "USA", avatar: "..." films: [1, 2] }, 2: { name: "Ewan McGregor", avatar: "..." }, 3: { name: "Natalie Portman", avatar: "..." }, 4: { name: "Hayden Christensen", avatar: "..." }, 5: { name: "James Cameron", avatar: "..." }, }, films: { 1: { title: "Star Wars: Episode I - The Phantom Menace", actors: [2, 3], director: 1, thumbnail: "..." }, 2: { title: "Star Wars: Episode II - Attack of the Clones", actors: [3, 4], thumbnail: "..." }, 3: { title: "The Terminator", director: 5, thumbnail: "..." }, } } }

Let’s analyze how these three methods compare to each other, in terms of speed and the amount of data retrieved.


Through REST, having to fetch 7 requests just to render one component can be very slow, mostly on mobile and shaky data connections. Hence, the jump from REST to GraphQL represents a great deal for speed, because we are able to render a component with only one request.

PoP, because it can fetch all data for many components in one request, will be faster for rendering many components at once; however, most likely there is no need for this. Having components be rendered in order (as they appear in the page), is already a good practice, and for those components which appear under the fold there is certainly no rush to render them. Hence, both the schema-based and component-based APIs are already pretty good and clearly superior to a resource-based API.

Amount of Data

On each request, data in the GraphQL response may be duplicated: actress “Natalie Portman” is fetched twice in the response from the first component, and when considering the joint output for the two components, we can also find shared data, such as film Star Wars: Episode I — The Phantom Menace.

PoP, on the other hand, normalizes the database data and prints it only once, however, it carries the overhead of printing the module structure. Hence, depending on the particular request having duplicated data or not, either the schema-based API or the component-based API will have a smaller size.

In conclusion, a schema-based API such as GraphQL and a component-based API such as PoP are similarly good concerning performance, and superior to a resource-based API such as REST.

Recommended reading: Understanding And Using REST APIs

Particular Properties Of A Component-Based API

If a component-based API is not necessarily better in terms of performance than a schema-based API, you may be wondering, then what am I trying to achieve with this article?

In this section, I will attempt to convince you that such an API has incredible potential, providing several features which are very desirable, making it a serious contender in the world of APIs. I describe and demonstrate each of its unique great features below.

The Data To Be Retrieved From The Database Can Be Inferred From The Component Hierarchy

When a module displays a property from a DB object, the module may not know, or care, what object it is; all it cares about is defining what properties from the loaded object are required.

For instance, consider the image below. A module loads an object from the database (in this case, a single post), and then its descendant modules will show certain properties from the object, such as title and content:

Shown data is defined at different intervals
While some modules load the database object, others load properties. (Large preview)

Hence, along the component hierarchy, the “dataloading” modules will be in charge of loading the queried objects (the module loading the single post, in this case), and its descendant modules will define what properties from the DB object are required (title and content, in this case).

Fetching all the required properties for the DB object can be done automatically by traversing the component hierarchy: starting from the dataloading module, we iterate all its descendant modules all the way down until reaching a new dataloading module, or until the end of the tree; at each level we obtain all required properties, and then merge all properties together and query them from the database, all of them only once.

In the structure below, module single-post fetches the results from the DB (the post with ID 37), and submodules post-title and post-content define properties to be loaded for the queried DB object (title and content respectively); submodules post-layout and fetch-next-post-button do not require any data fields.

"single-post" => Load objects with object type "post" and ID 37 modules "post-layout" modules "post-title" => Load property "title" "post-content" => Load property "content" "fetch-next-post-button"

The query to be executed is calculated automatically from the component hierarchy and their required data fields, containing all the properties needed by all the modules and their submodules:

SELECT title, content FROM posts WHERE id = 37

By fetching the properties to retrieve directly from the modules, the query will be automatically updated whenever the component hierarchy changes. If, for instance, we then add submodule post-thumbnail, which requires data field thumbnail:

"single-post" => Load objects with object type "post" and ID 37 modules "post-layout" modules "post-title" => Load property "title" "post-content" => Load property "content" "post-thumbnail" => Load property "thumbnail" "fetch-next-post-button"

Then the query is automatically updated to fetch the additional property:

SELECT title, content, thumbnail FROM posts WHERE id = 37

Because we have established the database object data to be retrieved in a relational manner, we can also apply this strategy among the relationships between database objects themselves.

Consider the image below: Starting from the object type post and moving down the component hierarchy, we will need to shift the DB object type to user and comment, corresponding to the post’s author and each of the post’s comments respectively, and then, for each comment, it must change the object type once again to user corresponding to the comment’s author.

Moving from a database object to a relational object (possibly changing the object type, as in post => author going from post to user, or not, as in author => followers going from user to user) is what I call “switching domains”.

Showing data for relational objects
Changing the DB object from one domain to another. (Large preview)

After switching to a new domain, from that level at the component hierarchy downwards, all required properties will be subjected to the new domain:

  • name is fetched from the user object (representing the post’s author),
  • content is fetched from the comment object (representing each of the post’s comments),
  • name is fetched from the user object (representing the author of each comment).

Traversing the component hierarchy, the API knows when it is switching to a new domain and, appropriately, update the query to fetch the relational object.

For example, if we need to show data from the post’s author, stacking submodule post-author will change the domain at that level from post to the corresponding user, and from this level downwards the DB object loaded into the context passed to the module is the user. Then, submodules user-name and user-avatar under post-author will load properties name and avatar under the user object:

"single-post" => Load objects with object type "post" and ID 37 modules "post-layout" modules "post-title" => Load property "title" "post-content" => Load property "content" "post-author" => Switch domain from "post" to "user", based on property "author" modules "user-layout" modules "user-name" => Load property "name" "user-avatar" => Load property "avatar" "fetch-next-post-button" 

Resulting in the following query:

SELECT p.title, p.content,,, u.avatar FROM posts p INNER JOIN users u WHERE = 37 AND =

In summary, by configuring each module appropriately, there is no need to write the query to fetch data for a component-based API. The query is automatically produced from the structure of the component hierarchy itself, obtaining what objects must be loaded by the dataloading modules, the fields to retrieve for each loaded object defined at each descendant module, and the domain switching defined at each descendant module.

Adding, removing, replacing or altering any module will automatically update the query. After executing the query, the retrieved data will be exactly what is required — nothing more or less.

Observing Data And Calculating Additional Properties

Starting from the dataloading module down the component hierarchy, any module can observe the returned results and calculate extra data items based on them, or feedback values, which are placed under entry moduledata.

For instance, module fetch-next-post-button can add a property indicating if there are more results to fetch or not (based on this feedback value, if there aren’t more results, the button will be disabled or hidden):

{ moduledata: { "page": { modules: { "single-post": { modules: { "fetch-next-post-button": { feedback: { hasMoreResults: true } } } } } } }

Implicit Knowledge Of Required Data Decreases Complexity And Makes The Concept Of An “Endpoint” Become Obsolete

As shown above, the component-based API can fetch exactly the required data, because it has the model of all components on the server and what data fields are required by each component. Then, it can make the knowledge of the required data fields implicit.

The advantage is that defining what data is required by the component can be updated just on the server-side, without having to redeploy JavaScript files, and the client can be made dumb, just asking the server to provide whatever data it is that it needs, thus decreasing the complexity of the client-side application.

In addition, calling the API to retrieve the data for all components for a specific URL can be carried out simply by querying that URL plus adding the extra parameter output=json to indicate returning API data instead of printing the page. Hence, the URL becomes its own endpoint or, considered in a different way, the concept of an “endpoint” becomes obsolete.

Requests to fetch resources with different APIs
Requests to fetch resources with different APIs. (Large preview)

Retrieving Subsets Of Data: Data Can Be Fetched For Specific Modules, Found At Any Level Of The Component Hierarchy

What happens if we don’t need to fetch the data for all modules in a page, but simply the data for a specific module starting at any level of the component hierarchy? For instance, if a module implements an infinite-scroll, when scrolling down we must fetch only new data for this module, and not for the other modules on the page.

This can be accomplished by filtering the branches of the component hierarchy that will be included in the response, to include properties only starting from the specified module and ignore everything above this level. In my implementation (which I will describe in an upcoming article), the filtering is enabled by adding parameter modulefilter=modulepaths to the URL, and the selected module (or modules) is indicated through a modulepaths[] parameter, where a “module path” is the list of modules starting from the top-most module to the specific module (e.g. module1 => module2 => module3 has module path [module1, module2, module3] and is passed as a URL parameter as module1.module2.module3).

For instance, in the component hierarchy below every module has an entry dbobjectids:

"module1" dbobjectids: [...] modules "module2" dbobjectids: [...] modules "module3" dbobjectids: [...] "module4" dbobjectids: [...] "module5" dbobjectids: [...] modules "module6" dbobjectids: [...]

Then requesting the webpage URL adding parameters modulefilter=modulepaths and modulepaths[]=module1.module2.module5 will produce the following response:

"module1" modules "module2" modules "module5" dbobjectids: [...] modules "module6" dbobjectids: [...]

In essence, the API starts loading data starting from module1 => module2 => module5. That’s why module6, which comes under module5, also brings its data while module3 and module4 do not.

In addition, we can create custom module filters to include a pre-arranged set of modules. For instance, calling a page with modulefilter=userstate can print only those modules which require user state for rendering them in the client, such as modules module3 and module6:

"module1" modules "module2" modules "module3" dbobjectids: [...] "module5" modules "module6" dbobjectids: [...]

The information of which are the starting modules comes under section requestmeta, under entry filteredmodules, as an array of module paths:

requestmeta: { filteredmodules: [ ["module1", "module2", "module3"], ["module1", "module2", "module5", "module6"] ]

This feature allows to implement an uncomplicated Single-Page Application, in which the frame of the site is loaded on the initial request:

"page" modules "navigation-top" dbobjectids: [...] "navigation-side" dbobjectids: [...] "page-content" dbobjectids: [...]

But, from them on, we can append parameter modulefilter=page to all requested URLs, filtering out the frame and bringing only the page content:

"page" modules "navigation-top" "navigation-side" "page-content" dbobjectids: [...]

Similar to module filters userstate and page described above, we can implement any custom module filter and create rich user experiences.

The Module Is Its Own API

As shown above, we can filter the API response to retrieve data starting from any module. As a consequence, every module can interact with itself from client to server just by adding its module path to the webpage URL in which it has been included.

I hope you will excuse my over-excitement, but I truly can’t emphasize enough how wonderful this feature is. When creating a component, we don’t need to create an API to go alongside with it to retrieve data (REST, GraphQL, or anything at all), because the component is already able to talk to itself in the server and load its own data — it is completely autonomous and self-serving.

Each dataloading module exports the URL to interact with it under entry dataloadsource from under section datasetmodulemeta:

{ datasetmodulemeta: { "module1": { modules: { "module2": { modules: { "module5": { meta: { dataloadsource: "https://page-url/?modulefilter=modulepaths&modulepaths[]=module1.module2.module5" }, modules: { "module6": { meta: { dataloadsource: "https://page-url/?modulefilter=modulepaths&modulepaths[]=module1.module2.module5.module6" } } } } } } } } }

Fetching Data Is Decoupled Across Modules And DRY

To make my point that fetching data in a component-based API is highly decoupled and DRY (Don’t Repeat Yourself), I will first need to show how in a schema-based API such as GraphQL it is less decoupled and not DRY.

In GraphQL, the query to fetch data must indicate the data fields for the component, which may include subcomponents, and these may also include subcomponents, and so on. Then, the topmost component needs to know what data is required by every one of its subcomponents too, as to fetch that data.

For instance, rendering the <FeaturedDirector> component might require the following subcomponents:

Render <FeaturedDirector>: <div> Country: {country} {foreach films as film} <Film film={film} /> {/foreach} </div> Render <Film>: <div> Title: {title} Pic: {thumbnail} {foreach actors as actor} <Actor actor={actor} /> {/foreach} </div> Render <Actor>: <div> Name: {name} Photo: {avatar} </div> 

In this scenario, the GraphQL query is implemented at the <FeaturedDirector> level. Then, if subcomponent <Film> is updated, requesting the title through property filmTitle instead of title, the query from the <FeaturedDirector> component will need to be updated, too, to mirror this new information (GraphQL has a versioning mechanism which can deal with this problem, but sooner or later we should still update the information). This produces maintenance complexity, which could be difficult to handle when the inner components often change or are produced by third-party developers. Hence, components are not thoroughly decoupled from each other.

Similarly, we may want to render directly the <Film> component for some specific film, for which then we must also implement a GraphQL query at this level, to fetch the data for the film and its actors, which adds redundant code: portions of the same query will live at different levels of the component structure. So GraphQL is not DRY.

Because a component-based API already knows how its components wrap each other in its own structure, then these problems are completely avoided. For one, the client is able to simply request the required data it needs, whichever this data is; if a subcomponent data field changes, the overall model already knows and adapts immediately, without having to modify the query for the parent component in the client. Therefore, the modules are highly decoupled from each other.

For another, we can fetch data starting from any module path, and it will always return the exact required data starting from that level; there are no duplicated queries whatsoever, or even queries to start with. Hence, a component-based API is fully DRY. (This is another feature that really excites me and makes me get wet.)

(Yes, pun fully intended. Sorry about that.)

Retrieving Configuration Values In Addition To Database Data

Let’s revisit the example of the featured-director component for the IMDB site described above, which was created — you guessed it! — with Bootstrap. Instead of hardcoding the Bootstrap classnames or other properties such as the title’s HTML tag or the avatar max width inside of JavaScript files (whether they are fixed inside the component, or set through props by parent components), each module can set these as configuration values through the API, so that then these can be directly updated on the server and without the need to redeploy JavaScript files. Similarly, we can pass strings (such as the title Featured director) which can be already translated/internationalized on the server-side, avoiding the need to deploy locale configuration files to the front-end.

Similar to fetching data, by traversing the component hierarchy, the API is able to deliver the required configuration values for each module and nothing more or less.

The configuration values for the featured-director component might look like this:

{ modulesettings: { "page": { modules: { "featured-director": { configuration: { class: "alert alert-info", title: "Featured director", titletag: "h3" }, modules: { "director-films": { configuration: { classes: { wrapper: "media", avatar: "mr-3", body: "media-body", films: "row", film: "col-sm-6" }, avatarmaxsize: "100px" }, modules: { "film-actors": { configuration: { classes: { wrapper: "card", image: "card-img-top", body: "card-body", title: "card-title", avatar: "img-thumbnail" } } } } } } } } } }

Please notice how — because the configuration properties for different modules are nested under each module’s level — these will never collide with each other if having the same name (e.g. property classes from one module will not override property classes from another module), avoiding having to add namespaces for modules.

Higher Degree Of Modularity Achieved In The Application

According to Wikipedia, modularity means:

The degree to which a system’s components may be separated and recombined, often with the benefit of flexibility and variety in use. The concept of modularity is used primarily to reduce complexity by breaking a system into varying degrees of interdependence and independence across and ‘hide the complexity of each part behind an abstraction and interface’.

Being able to update a component just from the server-side, without the need to redeploy JavaScript files, has the consequence of better reusability and maintenance of components. I will demonstrate this by re-imagining how this example coded for React would fare in a component-based API.

Let’s say that we have a <ShareOnSocialMedia> component, currently with two items: <FacebookShare> and <TwitterShare>, like this:

Render <ShareOnSocialMedia>: <ul> <li>Share on Facebook: <FacebookShare url={window.location.href} /></li> <li>Share on Twitter: <TwitterShare url={window.location.href} /></li> </ul>

But then Instagram got kind of cool, so we need to add an item <InstagramShare> to our <ShareOnSocialMedia> component, too:

Render <ShareOnSocialMedia>: <ul> <li>Share on Facebook: <FacebookShare url={window.location.href} /></li> <li>Share on Twitter: <TwitterShare url={window.location.href} /></li> <li>Share on Instagram: <InstagramShare url={window.location.href} /></li> </ul>

In the React implementation, as it can be seen in the linked code, adding a new component <InstagramShare> under component <ShareOnSocialMedia> forces to redeploy the JavaScript file for the latter one, so then these two modules are not as decoupled as they could be.

In the component-based API, though, we can readily use the relationships among modules already described in the API to couple the modules together. While originally we will have this response:

{ modulesettings: { "share-on-social-media": { modules: { "facebook-share": { configuration: {...} }, "twitter-share": { configuration: {...} } } } }

After adding Instagram we will have the upgraded response:

{ modulesettings: { "share-on-social-media": { modules: { "facebook-share": { configuration: {...} }, "twitter-share": { configuration: {...} }, "instagram-share": { configuration: {...} } } } }

And just by iterating all the values under modulesettings["share-on-social-media"].modules, component <ShareOnSocialMedia> can be upgraded to show the <InstagramShare> component without the need to redeploy any JavaScript file. Hence, the API supports the addition and removal of modules without compromising code from other modules, attaining a higher degree of modularity.

Native Client-Side Cache/Data Store

The retrieved database data is normalized in a dictionary structure, and standardized so that, starting from the value on dbobjectids, any piece of data under databases can be reached just by following the path to it as indicated through entries dbkeys, whichever way it was structured. Hence, the logic for organizing data is already native to the API itself.

We can benefit from this situation in several ways. For instance, the returned data for each request can be added into a client-side cache containing all data requested by the user throughout the session. Hence, it is possible to avoid adding an external data store such as Redux to the application (I mean concerning the handling of data, not concerning other features such as the Undo/Redo, the collaborative environment or the time-travel debugging).

Also, the component-based structure promotes caching: the component hierarchy depends not on the URL, but on what components are needed in that URL. This way, two events under /events/1/ and /events/2/ will share the same component hierarchy, and the information of what modules are required can be reutilized across them. As a consequence, all properties (other than database data) can be cached on the client after fetching the first event and reutilized from then on, so that only database data for each subsequent event must be fetched and nothing else.

Extensibility And Re-purposing

The databases section of the API can be extended, enabling to categorize its information into customized subsections. By default, all database object data is placed under entry primary, however, we can also create custom entries where to place specific DB object properties.

For instance, if the component “Films recommended for you” described earlier on shows a list of the logged-in user’s friends who have watched this film under property friendsWhoWatchedFilm on the film DB object, because this value will change depending on the logged-in user then we save this property under a userstate entry instead, so when the user logs out, we only delete this branch from the cached database on the client, but all the primary data still remains:

{ databases: { userstate: { films: { 5: { friendsWhoWatchedFilm: [22, 45] }, } }, primary: { films: { 5: { title: "The Terminator" }, } "people": { 22: { name: "Peter", }, 45: { name: "John", }, }, } }

In addition, up to a certain point, the structure of the API response can be re-purposed. In particular, the database results can be printed in a different data structure, such as an array instead of the default dictionary.

For instance, if the object type is only one (e.g. films), it can be formatted as an array to be fed directly into a typeahead component:

[ { title: "Star Wars: Episode I - The Phantom Menace", thumbnail: "..." }, { title: "Star Wars: Episode II - Attack of the Clones", thumbnail: "..." }, { title: "The Terminator", thumbnail: "..." },

Support For Aspect-Oriented Programming

In addition to fetching data, the component-based API can also post data, such as for creating a post or adding a comment, and execute any kind of operation, such as logging the user in or out, sending emails, logging, analytics, and so on. There are no restrictions: any functionality provided by the underlying CMS can be invoked through a module — at any level.

Along the component hierarchy, we can add any number of modules, and each module can execute its own operation. Hence, not all operations must necessarily be related to the expected action of the request, as when doing a POST, PUT or DELETE operation in REST or sending a mutation in GraphQL, but can be added to provide extra functionalities, such as sending an email to the admin when a user creates a new post.

So, by defining the component hierarchy through dependency-injection or configuration files, the API can be said to support Aspect-oriented programming, “a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns.”

Recommended reading: Protecting Your Site With Feature Policy

Enhanced Security

The names of the modules are not necessarily fixed when printed in the output, but can be shortened, mangled, changed randomly or (in short) made variable any way intended. While originally thought for shortening the API output (so that module names carousel-featured-posts or drag-and-drop-user-images could be shortened to a base 64 notation, such as a1, a2 and so on, for the production environment), this feature allows to frequently change the module names in the response from the API for security reasons.

For instance, input names are by default named as their corresponding module; then, modules called username and password, which are to be rendered in the client as <input type="text" name="{input_name}"> and <input type="password" name="{input_name}"> respectively, can be set varying random values for their input names (such as zwH8DSeG and QBG7m6EF today, and c3oMLBjo and c46oVgN6 tomorrow) making it more difficult for spammers and bots to target the site.

Versatility Through Alternative Models

The nesting of modules allows to branch out to another module to add compatibility for a specific medium or technology, or change some styling or functionality, and then return to the original branch.

For instance, let’s say the webpage has the following structure:

"module1" modules "module2" modules "module3" "module4" modules "module5" modules "module6"

In this case, we’d like to make the website also work for AMP, however, modules module2, module4 and module5 are not AMP compatible. We can branch these modules out into similar, AMP-compatible modules module2AMP, module4AMP and module5AMP, after which we keep loading the original component hierarchy, so then only these three modules are substituted (and nothing else):

"module1" modules "module2AMP" modules "module3" "module4AMP" modules "module5AMP" modules "module6"

This makes it fairly easy to generate different outputs from a single codebase, adding forks only here and there as needed, and always scoped and restrained to individual modules.

Demonstration Time

The code implementing the API as explained in this article is available in this open-source repository.

I have deployed the PoP API under for demonstration purposes. The website runs on WordPress, so the URL permalinks are those typical to WordPress. As noted earlier, through adding parameter output=json to them, these URLs become their own API endpoints.

The site is backed by the same database from the PoP Demo website, so a visualization of the component hierarchy and retrieved data can be done querying the same URL in this other website (e.g. visiting the explains the data from

The links below demonstrate the API for cases described earlier on:

Example of JSON code returned by the API
Example of JSON code returned by the API. (Large preview)


A good API is a stepping stone for creating reliable, easily maintainable and powerful applications. In this article, I have described the concepts powering a component-based API which, I believe, is a pretty good API, and I hope I have convinced you too.

So far, the design and implementation of the API have involved several iterations and taken more than five years — and it’s not completely ready yet. However, it is in a pretty decent state, not ready for production but as a stable alpha. These days, I am still working on it; working on defining the open specification, implementing the additional layers (such as rendering) and writing documentation.

In an upcoming article, I will describe how my implementation of the API works. Until then, if you have any thoughts about it — regardless whether positive or negative — I would love to read your comments below.

Smashing Editorial (rb, ra, yk, il)
What’s New for Designers, January 2019

New year, new design tools. As your start regrouping and reorganizing in 2019, why not make good on those resolutions and try a new design element or two. We’ve got plenty to choose from here.

If we’ve missed something that you think should have been on the list, let us know in the comments. And if you know of a new app or resource that should be featured next month, tweet it to @carriecousins to be considered!

UI Bundle

UI Bundle is a search tool to help you find fonts, icons, UI kits, mockups and more design goodies. You can browse options right on the home screen or use the search bar to find the perfect set of tools. And the best part? All of the tools and resources are free to download and use.

Rakuten RapidAPI

Rakuten RapidAPI helps you discover and connect to APIs in the world’s largest hub. Search for popular, recommended or task specific APIs, test in-browser and connect using code snippets. Plus, you can manage it all from a single dashboard.

Free Image and Photo Resizer

Free Image and Photo Resizer gets your images ready for website and social media use without expensive software. Just upload your image and the tool will create a crop that fits common social media channels and web specifications. You can also create custom sizes.

SVG Gradient Map Filter

SVG Gradient Map Filter is a nifty little tool that puts a great color overlay on images. You can use ready-made palettes or edit them and get yours.


WebsiteVoice turns text into high-quality audio for users who want to listen to your content. (We all know that voice interfaces are all the rage!) Voice interfaces can increase user engagement, accessibility and help grow followers and subscribers to content. The tool is customizable and free.


Screen.Guru takes all the guesswork out of creating clean website screenshots. Just enter a URL and get a grab that you can use in projects.


Blobmaker helps you create trendy bubbles and blobs for website designs. With plenty of settings to tweak this is as fun to play with as it is useful.


Pika is a “search engine” for finding modern packages on npm. You can browse and search for smaller, faster JavaScript bundles.

UI Sounds

UI Sounds shows what a noisy place the internet has become. It’s a collection of all the beeps, dings and ditties that are part of our everyday browsing habits.

Magic Sketchpad

Magic Sketchpad uses machine learning to finish your doodles and sketches. It’s pretty addictive to play with.

Essentials Icon Pack

Essentials Icon Pack is a set of common icons that work for pretty much every project. The tool from InVision is based on their most popular icons and includes 140 icons.

Vector Icons

Freebiesbug has a set of 150 vector icons that are free to try. The set includes plenty of icons in multiple categories – weather, music, health, food and more – in colored, outline and monochromatic options. Each comes in AI, EPS and PNG format for easy customization and scalable use.

UI Logos

UI Logos is a collection of free professional logo placeholders for projects. There are more than 25 logos and a plugin to help you get elements that will make your mockups look more polished. It works with Sketch and Adobe XD.

Space Marble Backgrounds

Space Marble Backgrounds is a fun set of background images with a design that’s out of this world! The collection includes 12 handmade options for a variety of project types.

Social Meet Up UI Kit

Social Meet Up UI Kit is a free collection of Adobe XD with more than 80 screens in six categories to speed up your workflow for projects. Everything is customizable and comes with a pretty nifty color and typography palette that you can use (or not).

Design Camera

Design Camera is an app for your Mac that lets you create, capture and animate 3D mockups for your digital designs in a matter of seconds. Designers from Shopify, Google, Starbucks, Uber, Sketch and Dropbox are already in the beta.

CSS Puns

CSS Puns is sure to make you giggle … if you understand code anyway. Play with the tool only or buy merchandise if there’s a pun you really like.

Material Design Palette Generator

Material Design Palette Generator pulls the colors of Material Design out of Google’s documentation for easy use. Turn a hex code into a full palette right on the screen.


Alvaro is a condensed sans serif display font that’s made to be big. It includes 221 characters in an uppercase style.

Classical Monoline Script

Classical is a fun and readable script that has a neutral feel. It includes beautiful upper- and lowercase options as well as alternates, ligatures and swashes.

Honeymoon Avenue Serif Font

Honeymoon Avenue Serif Font is a modern style serif with alternating thin and thick stroke widths. It’s a little on the thin side and is easy to read. The free version includes uppercase letters.

PT Root

PT Root is part of the PT Root typeface family. It includes four styles of normal proportions intended for screen reading, interfaces, websites and wayfinding systems. PT Root is a modern uniwidth sans serif whose individual character widths are constant across all weights.


Soulcraft is a free OpenType variable font designed with the idea of emulating vernacular lettering. You can change the width and slant of each individual character without relying on pre-defined font weights.

The Rustic

The Rustic is a simple uppercase display typeface in a fun style. It includes alternates for an interesting look.

Add Realistic Chalk and Sketch Lettering Effects with Sketch’it – only $5!

p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

Popular Design News of the Week: January 14, 2019 – January 20, 2019

Every week users submit a lot of interesting stuff on our sister site Webdesigner News, highlighting great content from around the web that can be of interest to web designers. 

The best way to keep track of all the great stories and news being posted is simply to check out the Webdesigner News site, however, in case you missed some here’s a quick and useful compilation of the most popular designer news that we curated from the past week.

Note that this is only a very small selection of the links that were posted, so don’t miss out and subscribe to our newsletter and follow the site daily for all the news.



Brutalist Websites are Dead


Tastemaking: 2019 Design Trends


Will Adobe XD Kill Sketch and InVision?


HTML5 Input Types: Where are They Now?


Re: Pleasing Color Palettes


6 Best Drag and Drop WordPress Page Builders Compared (2019)


Why I Don’t Use Google Analytics


Tint and Shade Generator


How to Win all Arguments About Color


Security Checklist


You Pay Me, but I Don’t Work for You


An Egg Beats Kylie Jenner to Become the Most Liked Instagram Photo… Ever


Icons. Good or Bad? As Always, it Depends


The Flexbox Holy Albatross


A Collection of Great UI Designs


Pentagram Case Study on the Slack Rebrand


Should Design Tools Code?


Top 5 Popular Free Material Design Frameworks for Developers


Why Most of 2018’s Tech Predictions were Wrong


What is your UX Process?


Inspiration: Figmas 404 Page


3 UX Takeaways from Redesigning Google Translate


EU Article 13 is Almost Finished – And it will Change the Internet as We Know it


Want more? No problem! Keep track of top design news from around the web with Webdesigner News.

Add Realistic Chalk and Sketch Lettering Effects with Sketch’it – only $5!

p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

Monthly Web Development Update 1/2019: Rethinking Habits And Finding Custom Solutions

Monthly Web Development Update 1/2019: Rethinking Habits And Finding Custom Solutions

Monthly Web Development Update 1/2019: Rethinking Habits And Finding Custom Solutions

Anselm Hannemann

What could be better than starting the new year with some new experiments? Today I figured it was time to rethink JavaScript tooling in one of my projects. And since we wrote everything in plain ECMAScript modules already, I thought it would be easy to serve them natively now and remove all the build and transpilation steps. Until I realized that — although we wrote most code ourselves — we have a couple of third-party dependencies in there and, of course, not all of them are ECMAScript modules. So for now, I have to give up my plans to remove all the build steps and continue to bundle and transpile things, but I’ll try to figure out a better solution to modernize and simplify our tooling setup while providing a smaller bundle to our users.

Another experiment: Just a few weeks ago I had to build a simple “go to the top of the page” button for a website. I used requestAnimationFrame and similar stuff to optimize event handling, but today I found a way nicer and more efficient solution that uses IntersectionObserver to toggle the button on the viewport. You will find that article in the JavaScript section below. The reason I wanted to share these little stories is because I believe that the most important thing is that we review our habits and current solutions and see whether there are better, newer, simpler ideas that could improve a product. Keep playing, keep researching, and be sure to rethink existing systems from time to time.



Web Performance


Infographic showing how authentication and verification work without a password
Passwordless authentication? The WebAuthn API makes it possible. (Image credit)


An example text with randomly generated underlines.
Una Kravet’s “super underline” example uses randomly generated underlines for each element. Made possible with Houdini and the Paint API. (Image credit)

Work & Life

  • “Feeling a sense of accomplishment is an important part of our sense of self-worth. Beating up on yourself because you think you could have accomplished more can dent your confidence and self-esteem and leave you feeling depleted at the end of the day.” Lisa Evans shares what we can do to avoid falling into that trap.
  • Itamar Turner-Trauring shares his thoughts on how to get a job with a good work-life balance when you’re competing against people who are willing to work long hours.
  • Is it a good idea to provide healthcare and treatment based on digital products like apps? And if so, what are the requirements, the standards for this? How can we ensure this is done ethically correct? How do we set the limits, the privacy boundaries, how far do we allow companies to go with experiments here? Would personalized content be fine? Is it okay to share data collected from our devices with healthcare providers or insurances? These are questions we will have to ask ourselves and find an individual answer for.
  • This article about how Millenials became the burnout generation hit me hard this week. I see myself in this group of people described as “Millenials” (I do think it affects way more people than just the 20-year-olds) and I could relate to so many of the struggles mentioned in there that I now think that these problems are bigger than I ever imagined. They will affect society, politics, each individual on our planet. Given that fact, it’s crazy to hear that most people today will answer that they don’t have a friend they could talk to about their fears and anything else that disturbs them while two decades ago the average answer was still around five. Let’s assure our friends that we’re there for them and that they can talk to us about tough things. 2019 should be a year in which we — in our circle of influence — make it great to live in a human community where we can think with excitement and happiness about our friends, neighbors, and people we work with or talk to on the Internet.
  • We all try to accommodate so many things at the same time: being successful and productive at work, at home, with our children, in our relationships, doing sports, mastering our finances, and some hobbies. But we blindly ignore that it’s impossible to manage all that on the same level at the same time. We feel regret when we don’t get everything done in a specific timeframe such as at the end of a calendar year. Shawn Blanc argues that we should celebrate what we did do instead of feeling guilty for what we didn’t do.

Going Beyond…

  • There are words, and then there are words. Many of us know how harmful “just” can be as a word, how prescriptive, how passively aggressive it is. Tobias Tom challenges whether “should” is a useful word by examining the implicit and the result of using it in our daily language. Why “should” can be harmful to you and to what you want to achieve.
  • “We all know what we stand for. The trick is to state our values clearly — and to stand by them,” says Ben Werdmuller and points out how important it is to think about your very own red line that you don’t want to cross regardless of external pressure you might face or money you might get for it.
  • Exciting news for climate improvement this week: A team of arborists has successfully cloned and grown saplings from the stumps of some of the world’s oldest and largest coast redwoods, some of which were 3,000 years old and measured 35 feet in diameter when they were cut down in the 19th and 20th centuries. Earlier this month, 75 of the cloned saplings were planted at the Presidio National Park in San Francisco. What makes this so special is the fact that these ancient trees can sequester 250 tons of carbon dioxide from the atmosphere over their lives, compared to 1 ton for an average tree.
  • The ongoing technological development and strive to build new services that automate more and more things make it even more critical to emphasize human connection. Companies that show no effort in improving things for their clients, their employees, or the environment will begin to struggle soon, Ryan Paugh says.
  • We usually don’t expect much nice news about technology inventions from the car industry and their willingness to share it with others. But Toyota now has decided to share their automated safety system ‘Guardian’ with competitors. It uses self-driving technology to keep cars from crashing. “We will not keep it proprietary to ourselves only. But we will offer it in some way to others, whether that’s through licensing or actual whole systems,” says Gill Pratt from the company.

Thank you for reading! I’m happy to be back with this new edition of my Web Development Update in 2019 and grateful for all your ongoing support. It makes me happy to hear that so many people find this resource helpful. So if you enjoyed it, please feel free to share it with people you know, give me feedback, or support it with a small amount of money. —Anselm

Smashing Editorial (cm)
How I Built a GPS-Powered Weather Clock With My Old iPhone 4

My first smartphone was an iPhone 4s. I remember the excitement of exploring its capabilities at a time when it was the coolest thing around. Eventually, of course, I replaced it with a newer model and the old iPhone, still in mint condition, gathered dust for two years. What a waste!

But was it? It occurred to me that I could repurpose the old iPhone to create a useful weather clock for our hallway.

Who needs Nest anyway?

In the process, I discovered that reusing an old device is not only fun and economical, it can also deepen your understanding of web standards. In this tutorial, I will show how I created a small web page to display the date, time, and current weather conditions based on the current GPS location. Together, we’ll retrieve weather data from a public API and hide an API key in a PHP file for security. Finally, we’ll look at adding a manifest file and meta tags so that users can save the page to a device’s home screen and then launch it as a standalone app, including a custom icon for it.

Here is a screen shot of what we’re aiming for:

Step 1: What time is it?

See the Pen Wall Clock by Steven Estrella (@sgestrella) on CodePen.

The HTML for the clock has some placeholder text that we will eventually replace. All we really need at this moment is a centered <main> container element and a couple of semantic <time> elements for the date and time. The <span> tag within the second <time> element will be styled specially to display the running seconds and the meridian. The datetime attribute within the <time> elements will be updated dynamically with JavaScript.

<main id="container" class="daymode"> <time id="date" datetime="" class="clocktext">Someday, Anymonth 15, 20XX</time> <time id="time" datetime="" class="clocktext">12:00<span>:00 PM</span></time>

A little responsive design is key here. We want this to fit nicely on an iPhone 4s screen or any other small-ish smartphone in both portrait and landscape modes. We also want it to work well on a desktop web browser, of course. We can’t use any bleeding-edge CSS or JavaScript, however, because older devices like my iPhone 4s won’t understand it.

I wound up taking things up a notch by creating styles specific for the time of day and we’ll definitely get to that as well. We could even leverage a media query to darken the daytime style for Mac users who have dark mode turned on in the latest MacOS.

The <span> tag with the running seconds and meridian will wrap nicely based on a width of 2em which is just large enough to accommodate two capital letters (i.e. AM and PM). The final CSS that’s needed is a media query to bump up font sizes when the clock is in landscape mode, or really any device with a viewport wider than 480px.

Here are the base styles we’re looking at, with the more decorative styles in the final app removed for brevity:

/* Base nighttime styles */
.nightmode { background-color: #121212; color: #fff;
} /* Base daytime styles */
.daymode { background-color: #87ceeb; color: #333;
} /* Target MacOS users who have Dark Mode enabled */
@media (prefers-color-scheme: dark) { .daymode { background-color: #003; color: #ffc; }
} /* Used to wrap any lines of text */
.clocktext { display: block; margin: 0; padding: 1px 0 0 0; text-align: center; white-space: nowrap; width: 100%;
} #date { font-size: 1.3rem; padding-top: 15px;
} #time { font-size: 5rem; margin: 1px 0 0 0;
} #time span { display: inline-block; font-size: 1.5rem; line-height: 1.5; margin: 0 0 0 0.5em; padding: 0; text-align: left; vertical-align: baseline; white-space: normal; width: 2em;
} @media (min-width: 480px){ #date {font-size: 2rem;} #time {font-size: 8rem;} #time span { font-size: 2rem; line-height: 2; }

For the JavaScript, I chose ES5 because many features of ES6 don’t work on the mobile Safari browser in iOS 9.35, which is the final iOS that runs on the iPhone 4s. Fortunately, ES5 is more than up to the task and the app runs properly on newer devices as well.

We need variables for the current date and time (now), the element that will display the date (dd), the element that will display the time (td) and the names of the months and days. Once the page is loaded, an init function is called to update the time every second (1000 milliseconds). The getClockStrings() function updates the value in the now Date object and returns an object containing HTML strings for the date and time. Then the updateTime() function updates the HTML to show the time. One lesser-used feature here is the inclusion of the toISOString() method of the Date object which adds a machine-readable date string to the datetime attribute of the two <time> elements.

Here’s what that boils dow to, using the JavaScript from the demo:

// NOTE: ES5 chosen instead of ES6 for compatibility with older mobile devices
var now, dd, td;
var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]; document.addEventListener("DOMContentLoaded", init, false);
function init() { dd = document.getElementById("date"); td = document.getElementById("time"); updateTime(); setInterval(updateTime,1000);
} function updateTime() { var clockdata = getClockStrings(); dd.innerHTML = clockdata.datehtml; td.innerHTML = clockdata.timehtml; dd.dateTime = now.toISOString(); td.dateTime = now.toISOString();
} function getClockStrings() { now = new Date(); var year = now.getFullYear(); var month = months[now.getMonth()]; var date = now.getDate(); var day = days[now.getDay()]; var hour = now.getHours(); var minutes = now.getMinutes(); var seconds = now.getSeconds(); var meridian = hour < 12 ? "AM" : "PM"; var clockhour = hour > 12 ? hour - 12 : hour; if (hour === 0) {clockhour = 12;} var clockminutes = minutes < 10 ? "0" + minutes : minutes; var clockseconds = seconds < 10 ? "0" + seconds : seconds; var datehtml = day + ", " + month + " " + date + ", " + year; var timehtml = clockhour + ":" + clockminutes + "<span>:" + clockseconds + " " + meridian + "</span>"; return {"datehtml":datehtml,"timehtml":timehtml};

Step 2: Where are you?

See the Pen Clock with GPS by Steven Estrella (@sgestrella) on CodePen.

The Geolocation API is an easy way to get the user’s accurate location. We can do that when the page loads, but good manners and Chrome’s best practices audit dictate that we ask the user to initiate the location feature. So, we must add a button and a

to the HTML to display the GPS information we receive.

These new items require their own styles — mine can be seen in the embedded Pen above. The important thing is to add the class selector rule for the infotext class as well as the two ID selector rules for the gpsbutton.

Finally, we’ll need to add the modified infotext class selector rule within the media query.

Again, the basic styles minus decorative styling for brevity:

/* The geolocation coordinates upon clicking GPS button */
.infotext { font-size: 1.3rem; line-height: 1.4; padding: 0 5px 0 5px; width: auto;
} /* The button itself */
#gpsbutton { -webkit-appearance: none; -moz-appearance: none; display: block; margin: 0 auto; width: auto; cursor: pointer;
} #gpsbutton:hover { /* Styles for the hover state */
} @media (min-width: 480px){ /* Add the rule below to the end of the media query */ .infotext {font-size: 1.8rem;}

The JavaScript requires a few new variables for the latitude, longitude, GPS

, and GPS
Behance Redesigns its Portfolios

There’s been a fairly big update to Behance, also known as DeviantArt for designers. Heck, I remember when I used DA for my portfolio. Good times.

Anyway… Behance. They’ve gone and updated what has to be the single most important aspect of their site: the portfolios. I mean, that’s what everybody is there for, no? They’re overhauled both the main portfolio view, as well as the experience of viewing individual projects in some small but important ways.


Customizable banners: You know those big image banners you get on sites like Twitter and Facebook? Behance has them too, now. Just upload a picture, crop it to your liking, and go. The stated purpose of these is to allow users to sort of set the tone, and get their branding right in there at the top.

Well, that’s the idea on all the other sites with the same feature, really. It’s a tried-and-proven technique. And if you don’t want a banner image, don’t upload one.

Bigger thumbnails: Not much to say, here. They took the old thumbnails, and scaled them right up. People get a better idea of what they’re looking at.


In their blog post on the update, Behance says, “… actions like Share, Save to Collection, Follow, and Appreciate are always present.” Basically, they kept this part of the UI very simple, and made the action buttons sticky, to reduce the effort it takes to interact with any particular project.

This is a simple but definitely good change. Projects tend to consist of one or more very, very long images, and scrolling can definitely take a while.

My Impressions

The whole experience is definitely tailored for desktop. That’s not to say people don’t look for designers on their phones, but if you really want to see the details, big screens make that easier. Adobe runs this show, so the decision is probably based on a fair amount of data telling them to cater to larger screens.

To be fair, any designer could probably have told them that. We might love our phones, but we work on desktops, laptops, and at the bare minimum, a big ole tablet. In fact, it would be fair to say that Behance is one of the few examples on the Internet where mobile-first design is… I’m going to say almost optional.

Beyond that, the changes just make sense to me. I do like it a lot when things are kept simple.

Add Realistic Chalk and Sketch Lettering Effects with Sketch’it – only $5!

p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

Grabbing Visual Attention With The Visual Cortex

Grabbing Visual Attention With The Visual Cortex

Grabbing Visual Attention With The Visual Cortex

Susan Weinschenk

(This is a sponsored post.) You are designing a landing page. The goal of the page is to get people to notice, and hopefully click on a button on the screen to subscribe to a monthly newsletter. “Make sure the button captures people’s attention” is the goal you’ve been given.

So how, exactly, do you do that?

Research on the visual cortex in the brain can give you some ideas. The visual cortex is the part of the brain that processes visual information. Each of the senses has an area of the brain where the signals for that sensory perception are usually sent and processed. The visual cortex is the largest of the sensory cortices because we are very visual animals.

Recommended reading: What Is The Role Of Creativity In UX Design?

The Pre-Attention Areas Of The Visual Cortex

There are special areas of the visual cortex that process visual information very quickly. These are called the “pre-attention” areas because they process information faster than someone may realize they’ve even noticed something visually.

Within the visual cortex are four areas called V1, V2, V3 and V4. These are the “pre-attention” areas of the visual cortex, and they are dedicated to very small and specific visual elements.

Let’s take a look at each one:


If one item is oriented differently than others, then it is noticed right away:

An image of fifteen short lines with one that stands out because it is oriented differently
(Large preview)

Size And Shape

If one item is either a different size or shape than others then it is noticed right away:

An image of twelve circles with one larger than the rest
(Large preview)


If one item is a different color than others around it then it is noticed right away:

An image of thirteen black circles with one of them shown in red
(Large preview)


If one item moves in quickly, especially if it zooms in from starting at a small size and then becoming larger quickly (think tiger running quickly towards you), that grabs attention.

But Only One At A Time

The interesting, not immediately obvious factor here is that if you use these factors together at the same time then nothing really attracts attention.

An abstract image of colorful circles in different sizes
(Large preview)

If you want to capture attention then, pick one of the methods and use it only.

Take a look at the two designs presented below. Which one draws your attention to the idea that you should enroll?

A minimalistic image that uses mostly two colors
(Large preview)
An image using a variety of colors and tones
(Large preview)

Obviously, the image that has just one color area draws your attention more, rather than the one area that is color.

The Fusiform Facial Area

The pre-attention areas of the visual cortex are not the only visual/brain connection to use. Another area of the brain you can tap to grab attention on a page could be the Fusiform Facial Area (or FFA).

The FFA is a special part of the brain that is sensitive to human faces. The FFA is located in the mid/social part of the brain near the amygdala which processes emotions. Faces grab attention because of the FFA.

A screenshot of the WIX website with a smiling person presented on the front page
(Large preview)

The FFA identifies:

  • Is this a face?
  • Someone I know?
  • Someone I know personally?
  • What are they feeling?

What stimulates the FFA?

  • Faces that look straight out stimulate the FFA.
  • Faces that are in profile may eventually stimulate the FFA, but not as quickly. In the example below the face is in profile and obscured by hair. It may not stimulate the FFA at all.
  • An image of a woman with her face covered by her hair so that her facial features cannot be seen well
    (Large preview)
  • Even inanimate objects like the picture of the car below may stimulate the FFA area if they have things that look like facial parts such as eyes and a mouth.
A picture of a car that looks like it has facial parts such as eyes and a mouth (front)
(Large preview)

Looking Where The Face Looks?

You may have seen the heat maps that show that if you show a face and the face is looking at an object (for example, a button or a product) on the screen then the person looking at the page will also look at the same object. Here’s an example:

An advertisement for Sunsilk Shampoo in which the lady in the picture is looking at the product compared to a picture of her looking straight
(Large preview)

The red areas show where people looked most. When the model looks at the shampoo bottle then people tend to look there too.

But be careful about drawing too many conclusions from this. Although the research shows that people’s eye gaze will follow the eye gaze of the photo, that doesn’t necessarily mean that people will take action. Highly emotional facial expressions lead to more action taking than just eye gaze.

Recommended reading: The Importance Of Macro And Micro-Moment Design


If you want to grab someone’s visual attention:

  • Use the pre-attention areas of the visual cortex: make everything on the page plain except for one element.


  • Show a large face, facing forward;
  • If you want to spur action have the face show a strong emotion;
  • Resist the urge to use many methods at once, such as a face, and color, and size, and shape, and orientation.

This article is part of the UX design series sponsored by Adobe. Adobe XD tool is made for a fast and fluid UX design process, as it lets you go from idea to prototype faster. Design, prototype and share — all in one app. You can check out more inspiring projects created with Adobe XD on Behance, and also sign up for the Adobe experience design newsletter to stay updated and informed on the latest trends and insights for UX/UI design.

Smashing Editorial (cm, ms, yk, il)
Slack Adopts Generic New Identity

There were few logos more recognizable than Slack’s. In the five years since the messaging service gained traction it has become a staple on desktops—as much a part of many professionals’ daily routine as email once was—and has grown to an $8bn valuation.

So it’s entirely understandable that when Slack revealed its new logo this week, there was a knee-jerk reaction from the design community. No matter how much they might protest, most people don’t like adapting to change.

Slack’s old logomark was a much-loved plaid hashtag. No, it was not perfect; the colors were a little dirty, especially where the bars overlapped, and it really wasn’t that flexible (as Slack themselves point out in their defensive blog post announcing the change).

Yes, the old logomark had problems, but they were problems that could have been fixed; if all you want to do is tackle legibility and color flexibility, why not just type ‘Slack’ in bright blue Gotham and have done with it.

The new logo was designed by the in-house team, together with Michael Beirut of Pentagram (yes, him again) together with assorted designers whose contributions didn’t warrant a namecheck in the press release.

The new logomark is crisp, clean, very well executed, and entirely lacking in soul. It follows a very sound, scientific logic, and yet lacks the personality that truly great identities have.

Whereas the original Slack logomark was both a hashtag, and a huddle with four different elements supporting each other; the new logomark feels more like four people with their backs to each other. No matter how insistent the press release, the new logomark does not evoke a spirit of teamwork—at least not as well has the hashtag did.

We don’t know what the brief was, and as such, we can only objectively talk about our own reactions to the change. But if this was a successful response to the brief, then the brief needed rewriting. The main problem being, that the bland non-committal look of the logomark makes it look like one of those free “logos for startups” that you can download as freebies in packs of a hundred.

As well as the logomark change, the type has been changed. Slack is currently looking at going public, and I can only conclude that there is some obscure fiscal law that requires all corporations listed on the stock market to abandon their humanist sans-serifs in favor of a geometric sans, because every single company with more than 10 employees is doing it.

The new logo has already been compared to rubber ducks, a web 2.0 logo, Joomla’s identity, and even a swastika. In fairness, bland as it is, the negative reaction to the new Slack logo is born out of a love for the old identity. Give it a few days for our eyes to adjust, and we’ll probably tune-out the change.

Add Realistic Chalk and Sketch Lettering Effects with Sketch’it – only $5!

p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}