![JavaScript modules.](https://2busy4it.com/wp-content/uploads/2024/06/javascript-modules.png)
JavaScript Modules (ES6 Modules) Explained: Tutorial for Beginners
![JavaScript modules.](https://2busy4it.com/wp-content/uploads/2024/06/javascript-modules.png)
Tips, Expertise, Articles and Advice from the Pro's for Your Website or Blog to Succeed
Over the past 12 months, I’ve shared hundreds of tools in my newsletter, Web Tools Weekly. I feature tons of practical libraries, helpers, and other useful things for front-end and full-stack developers. These tools span numerous categories, including JavaScript libraries and utilities, web frameworks, CSS generators, database tools, React components, CLI tools, and even ChatGPT and AI-based tools, the latter of which I’ve started covering regularly over the past year.
The 60 tools in this article were some of the most clicked web developer tools in my newsletter in 2023. As you’ll see, most of these are quite practical for front-end and full-stack development, so you’ll likely find lots that you’ll want to bookmark or use in an upcoming project. The list is roughly in reverse order in terms of popularity, so be sure to scroll down to see what the most popular tools of the year were!
Kuma UIKuma UI, which describes itself as “the future of CSS-in-JS”, is a headless, utility-first, zero-runtime component library that includes its own CSS-in-JS solution.
What makes Kuma UI different is its hybrid approach that allows for dynamic changes to your styles at runtime while still keeping the performance benefits of zero-runtime CSS-in-JS.
BoxsliderAlthough the use of carousel components has been discouraged in recent years, they still get asked for by my clients, and developers are always on the lookout for them. Boxslider is one such component.
This carousel, or content slider, includes seven slide transition effects that you can try out on the demo page, including a 3D cube effect, tile flip, and a simple fade.
EffectEffect is described as “a powerful TypeScript library designed to help developers easily create complex, synchronous, and asynchronous programs.”
The idea behind the effect is to help developers build robust and scalable applications by means of something called structured concurrency, a programming paradigm that allows multiple complex operations to run simultaneously.
HatTipIf you use Express.js for building Node.js apps, you’ll want to check out HatTip. It offers a solution similar to Express.js, but with a more universal approach.
HatTip is a set of JavaScript packages for building HTTP server apps and allows you to write server code that can be deployed anywhere – AWS, Cloudflare Workers, Vercel, and more.
LiveViewJSLiveViewJS is a simple yet powerful framework for building “LiveViews” in Node.js and Deno. LiveViews were popularized in Elixir’s Phoenix framework and involved moving state management and event handling to the server and doing HTML updates via WebSockets.
This technique allows you to build single-page app experiences with features like fast first paint, real-time and multi-player functionality, no need for a client-side routing solution, and lots more.
Scrollbar.appScrollbar.app is a one-stop reference and code generation tool for customizing browser scrollbars. You can live test and adjust the scrollbars directly on the page, then copy the CSS.
The scrollbar code involves using vendor-specific pseudo-elements but also incorporates the future-friendly scrollbar-color
.
OpenGPT is one of many ChatGPT-based tools that have been making the rounds over the past year or so. This one is an open-source AI platform that allows anyone to use and create ChatGPT-based applications.
The main platform for the service itself allows you to search a categorized directory of more than 11,000 ChatGPT apps.
Free IconsIcon sets always seem to make these end-of-year lists. Free Icons is a generically named set of 22,000+ icons that includes both brand icons and general-use ones.
All are in SVG format, and you can filter by keyword on the home page or grab the whole lot via the GitHub repository.
MaterializeMaterialize is an open-source framework of UI components based on Google’s Material Design guidelines.
The project, which includes 20+ categories of components, is a fork of an older project that’s no longer maintained.
qr-codeqr-code is an SVG-based web component that generates an animatable and customizable QR code. There’s an interactive demo page where you can try out the different animation effects.
The resulting QR code is SVG-based, the component has no dependencies, and it is easy to customize.
GradientGeneratorGradientGenerator is an interactive CSS gradient builder that allows you to build advanced layered gradients. You can customize your layered gradient using a whole slew of different settings and features.
The app also allows you to save gradients to your library and even import community-built gradients.
iDraw.jsiDraw.js is a simple JavaScript framework for creating apps that allow Canvas-based drawing.
There are some nice examples in a live playground where you can see the simplicity and ease of use of the API.
VanJSVanJS is a UI library similar to React but doesn’t use JSX, virtual DOM, transpiling, and so on. The idea is to avoid the overhead of configuration that’s normally associated with using a library like React.
The library claims to be the smallest UI library in the world at under 1kb. It has first-class support for TypeScript and naturally boasts strong performance compared to React, Vue, and so on.
Mamba UIMamba UI is the first of multiple Tailwind-based tools that made this year’s list. This is a UI library of 150+ components and templates based on the popular utility-first CSS framework.
The library includes pre-styled components in 40+ categories, and you can quickly grab the code for any component in HTML, Vue, or JSX format.
Termino.jsTermino.js is a dependency-free JavaScript component that lets you add embedded terminal-based animations, games, and apps to web pages.
It’s customizable and makes it easy to build terminal animations like keyboard typing effects. The demo page includes a few simple examples, including an embedded terminal app where the user can get info on any GitHub profile.
SVG Chart GeneratorSVG Chart Generator is a beautifully designed chart generator that lets you generate SVG-based charts in line or bar format.
The generator allows you to interactively customize the chart with width/height settings, number of points, smoothness, and more. You can also import your own data points.
PeepsLabPeepsLab is a simple online tool to customize your own unique illustrated user avatars. You can build your own avatars by cycling through the different options for skin color, hair color, facial hair, accessories, styles for head, face, etc.
Or you can simply hit the “Randomize” button to generate a random avatar before downloading it in PNG format.
Ribbon ShapesRibbon Shapes is an online gallery of pure CSS ribbons in just about any ribbon format you can imagine.
The gallery includes more than 100 ribbons, each created with a single HTML element and easy to customize using CSS variables.
big-AGIbig-AGI is a personal GPT-powered app that’s described as “the GPT application for professionals that need function, form, simplicity, and speed.”
It has a responsive, mobile-friendly interface and includes features like AI personas, text-to-image, voice, response streaming, code highlighting and execution, PDF import, and lots more.
Easy EmailEasy Email is a drag-and-drop email editor based on MJML, the popular HTML email authoring framework.
This solution allows you to transform structured JSON data into HTML that’s compatible with major email clients. Includes features for easily customizing blocks, components, and configuring themes.
CSS ComponentsCSS Components throws its hat into the CSS-in-JS space with this fresh solution, described as “not another styling system.”
This solution is a response to challenges inherent in using CSS-in-JS tools with React Server Components, and the library is inspired by another such tool, Stitches, and promises an improved developer experience.
ToasterToaster is an experimental pure CSS 3D editor that allows you to build models using pure HTML with CSS transforms.
The author acknowledges that the tool isn’t too practical and can currently only export/import in JSON format (no CSS export). With improved performance, this could be a useful tool.
FontpairFontpair isn’t a new resource, but it makes this year’s list. It’s a font directory specifically for finding fonts that match well together in your designs.
All the fonts are sourced from Google Fonts, and the pairings are manually curated by the authors.
BreaditBreadit is a modern, full-stack Reddit clone built with Next.js App Router, TypeScript, and Tailwind.
This is a nice app to learn and experiment with, featuring infinite scroll, NextAuth, image uploads, a feature-rich post editor, nested commenting, and lots more.
Keep ReactKeep React is a Tailwind and React-based component library that includes 40+ components and interactive elements.
The components are pre-designed, but all the components are easy to customize using Tailwind classes and are suitable for just about any project.
TW ElementsTW Elements is a massive library of more than 500 Bootstrap components recreated using Tailwind CSS. This is a great option for those already familiar with Bootstrap and looking for a modern alternative.
The library boasts better overall design and functionality compared to the original components in the Bootstrap framework, and you can easily search for components by keyword from the home page.
AutocompleteAutocomplete is an open-source, production-ready JavaScript library for building customizable autocomplete experiences for form inputs and search fields.
You can easily build an autocomplete experience by defining a container, data to populate it, and any virtual DOM solution (JS, React, Vue, Preact, and so on).
CSS LoadersCSS Loaders is a huge collection of more than 600 CSS loading animations organized under more than 30 categories.
This gallery includes just about any style of loader you can think of, and you can easily copy/paste the HTML/CSS for any loader with just a click.
FlectofyFlectofy is an interactive tool that provides an interface that allows you to build unique SVG shapes.
The styles of shapes here are pretty niche, so they wouldn’t be useful in too many contexts, but the way the interface works and the look of the shapes are certainly different.
PicyardPicyard is an app that generates screenshots with attractive backgrounds for use in mockups, social media posts, and so on.
The image/background tool is free, but the app also includes premium features for generating attractive code snippets, charts, mindmaps, timelines, and lots more.
UI ContentUI Content is described as “the best place to find professional placeholder text.” Includes placeholder text under seven different categories and also includes dummy SVG logos.
The idea here is to avoid typical “lorem ipsum” and use actual content instead to ensure your designs look closer to what the final product will be.
Vessel.jsVessel.js was one of the more unique projects I discovered over the past year. It’s a JavaScript library based on Three.js, the WebGL library, for conceptual ship design, in other words, building boats.
You can check out a number of examples in a gallery, and there’s also a tutorial that gets you up to speed on best practices for using the library — assuming this happens to be your niche!
Modern Font StacksModern Font Stacks is a resource to help you identify the best-performing font stacks. That is, the stacks are based on pre-installed default OS fonts.
You can choose from specific typographic categories like Traditional, Old Style, Neo-Grotesque, Monospace Code, Handwritten, and more. Again, these are generally fonts that are already available on Windows, Mac, Linux, iOS, and Android, giving you the best possible support without extra resource requests.
FancySymbolFancySymbol is a huge repository of ready-to-copy/paste special characters, text symbols, foreign language symbols, and more.
Includes more than 50 categories of symbols and also allows you to create unique and fancy copy/paste-able text like upside-down text or text written in “invisible ink,” among others.
Observable PlotObservable Plot is a JavaScript library for creating exploratory data visualizations (i.e., “plots”) using SVG-based charts.
The interface for the plots can include specific features like scales, projections, legends, curves, markers, and more. You’ll have to check out the documentation for the lowdown on these different features, which are illustrated using lots of interactive examples.
Washington Post Design SystemThe Washington Post Design System is a UI kit specifically built for properties associated with the Washington Post, a popular American daily newspaper and news outlet.
Although it is designed for WaPo’s engineers, it’s MIT-licensed and built-in React using Stitches and Radix UI. So, the customizable components and other assets may be of use if you’re using a similar tech stack.
FormSpamPreventionFormSpamPrevention isn’t a popular project, but it got quite a bit of traction when I shared it this past year. It offers a simple vanilla JavaScript and HTML solution for preventing form spam.
The script is based on using custom HTML tags for form content that gets converted to valid HTML tags.
ChatboxChatbox is a native app for Windows, Mac, and Linux that gives you access to an AI copilot on your desktop.
This particular tool isn’t strictly focused on web development, but it taps into various LLM models and can be used as an overall productivity app for all sorts of daily tech-related tasks.
CSS GeneratorsCSS Generators is not a single tool but a small collection of CSS generators, a popular kind of tool among front-end developers.
I like this set of generators because it has a few kinds you don’t see elsewhere: Two glow generators (for text and elements) and an underline generator.
Leporello.jsLeporello.js is an interactive functional programming IDE for JavaScript. This means your code is executed instantly as you type, potentially improving debugging processes.
Most of us are likely set on using a particular IDE, but if you’re into experimenting with new ones, this might be a good one to check out.
Calligrapher.aiCalligrapher.ai is an online tool for AI-generated handwriting samples that you can download as SVG.
There is no need to “write” anything; just type some text and customize stroke width and legibility, and the AI will do the rest. You can choose from 9 different print and cursive styles before generating the sample.
Clone UIClone UI is an AI-based tool that lets you generate UI components with a simple text prompt.
The app includes five free daily credits and includes a showcase of existing UI components generated by users.
Float UIFloat UI is a set of 100+ responsive and accessible UI components with RTL support. Also includes five templates.
The components and templates are built with Tailwind and are easy to customize. You can use them with React, Vue, and Svelte, or you can simply use HTML with Tailwind classes.
Calendar.jsCalendar.js is one of numerous date picker and calendar libraries available. This solution is lightweight and has no dependencies.
It’s fully configurable and includes drag-and-drop for events, exporting features, import from iCal and JSON, and lots more.
PCUIPCUI is yet another React-based component library that makes a list. This one provides a set of pre-styled components.
There’s a storybook that demonstrates all the basic components, and you can also view a few UI examples that show a few advanced examples in action (a to-do list and an example that keeps a “history” of the UI’s state).
Accessible Color Palette GeneratorAccessible Color Palette Generator is a great way to ensure any of your designs start with an accessible set of color choices.
You can generate a random accessible palette or enter any color, and the tool will generate an accessible palette for you based on the color you selected.
PicographyPicography is an alternative to the popular Unsplash and similarly offers high-resolution, royalty-free stock photos.
The photos are categorized and searchable and available for free use in commercial projects.
MailoMailo is a component-based, interactive HTML email layout designer that helps you easily build cross-client and responsive HTML emails.
Mailo includes pre-built components and team features, and the components are designed to work with just about any email client.
PinesPines is an aptly named UI component library that’s built with Tailwind and Alpine, the popular JavaScript framework that’s similar to a modern version of jQuery.
Pines includes dozens of components, including animations, sliders, tooltips, accordions, modals, and more.
Park UIPark UI is a set of beautifully designed components built on top of Ark UI, which itself is a set of accessible and customizable components.
Park UI can help you build your own design system, and the home page includes a neat interactive widget that demonstrates how easy it is to style the components. You can use Park UI with React, Vue, Solid, Panda CSS, and Tailwind.
IconhuntIconhunt is an icon search engine that lets you have access to 170,000+ free, open-source icons.
The icons can be downloaded in various formats, including Notion, Figma, SVG, or PNG, and you can customize the color of any icon you choose before downloading.
Sailboat UISailboat UI is a Tailwind-based UI component library that includes 150+ open-source components.
The components are very Bootstrap-esque, and you can search for and see live previews of the components in the docs.
ShaperShaper is a generative design tool for UI Interfaces that allows you to visually fiddle with a number of different interface features to customize your own UI.
It includes settings for custom typography, spacing, vertical rhythm, and so on, after which you can copy and paste the design tokens as CSS variables.
MailyMaily is an open-source editor that makes it easy to create beautiful HTML emails using a set of pre-built components.
It currently includes components in categories covering buttons, variables, text formatting, images, logos, alignment, dividers, spacers, footers, lists, and quotes, with more on the way.
Realtime ColorsRealtime Colors offers an interactive website that lets you test color palettes and typography on real live UI elements in real-time.
You can use the tool to generate palettes and deep links to a specific palette for sharing with others or demoing interfaces in dark or light modes.
StrawberryStrawberry is described as a “tiny” front-end framework that offers reactivity and composability with zero dependencies, no build step, and less than 3KB gzipped.
The idea here is not to offer a React or Vue alternative but something you’d use for simpler apps and other low-maintenance projects.
Swap.jsSwap.js is a JavaScript micro-library that uses HTML attributes to facilitate Ajax-style navigation in web pages in less than 100 lines of code.
This is in the same vein as libraries like HTMX and Hotwire, allowing you to replace content on the page by sending requests from the server as HTML fragments.
restorePhotos.iorestorePhotos.io is an open-source tool that uses AI to attempt to restore or correct old, blurry, or damaged photos.
You can deploy your own version locally or use their online tool to restore up to 5 photos per day for free.
Better SelectBetter Select is a web component that provides a minimal custom select element, something web developers have been grappling with accomplishing for decades!
This solution offers a fallback option and includes a small set of options via attributes that customize the functionality and look.
Space.jsInterestingly, Space.js ended up being the most-clicked tool in my newsletter the past year.
It’s one of two sibling libraries that are based on Three.js. The main one is for creating “future” UIs and panel components, and the other (called Alien.js) is for 3D utilities, materials, shaders, and physics.
What Was Your Favourite Tool of 2023?That wraps up this year’s roundup of the hottest front-end tools. I’m sure you’ll find at least a few of these to be of use in a new project in the coming months.
As always, I’m always looking for the latest in tools for front-end developers, so feel free to post your favourites from the past year in the comments, and you can subscribe to Web Tools Weekly if you want to keep up with new stuff regularly!
Over the past 12 months, we continue to see new free and open-source projects shared around the developer community. In my newsletter, Web Tools Weekly, I feature more than two dozen tools every week. As I do every year, I’ve gone through the numbers and put together what were the most popular tools according to my readers.
Some of these tools are interesting in a curious kind of way, but almost all of them are practical tools you can use in your projects today. I’ve listed these in reverse order of popularity based on unique clicks, so the most popular tools are at the bottom. Enjoy!
WebGi Camera Landing Page is a landing page template that uses GSAP, ScrollTrigger, and WebGI engine to create beautiful animated, scrollable one-page sites. The example website is impressive! It’s a mock Canon camera website with big graphics and animation.
Due to the potential for performance problems, this is obviously not for every kind of website. But it’s an option to consider if you want something bold and eye-catching.
CSS FingerprintOver the past few years, the concept of tracking users via nothing but CSS has been covered a lot. You can search the web for various articles on the topic, but CSS Fingerprint is somewhat of an all-in-one resource on the subject.
You can agree to visit a test page where you can view your own "CSS fingerprint" and the associated GitHub repo has a little more technical info.
PostSrc Tailwind ComponentsComponent libraries are always popular and anything associated with Tailwind tends to do well. PostSrc Tailwind Components includes more than 50 components divided into more than a dozen categories.
Includes components for UI elements like alerts, badges, buttons, breadcrumb navs, cards, CTAs, charts, forms, and more.
Almond.CSSAlmond.CSS is the first of three "class-less" CSS frameworks that made this year’s list. Even with the popularity of utility libraries like Tailwind, it’s interesting to see these kinds of projects do so well.
These libraries work similarly to a CSS reset or normalizer, but are a little more opinionated in terms of applied styles.
Piling.jsPiling.js is a JavaScript library that allows you to build interfaces where large amounts of items can be dragged and dropped into "piles".
It’s built on top of PixiJS, a 2D WebGL renderer and the demos allow you to easily customize the number of items on a page along with a number of other settings and configurations.
VirgoVirgo is a free HTML template from the folks at CodyHouse. It’s compatible with CodyHouse’s own framework and Tailwind and doesn’t have any third-party dependencies out-of-the-box.
Although it’s described as a "landing page template", it includes six pages and can be used freely in any project with some minor restrictions.
OnionOnion is a utility based on the most popular article on my personal blog. In that piece, I discuss a potential solution for animating "display: none" to "display:block" in CSS, which isn’t technically possible.
My solution uses a little bit of JavaScript to mimic the effect. This project, built by Parkle Lee, encapsulates the code from that article into an easy-to-use JavaScript utility.
MingCuteI probably come across at least 20 new icon libraries every year. MingCute is one of those and it seemed to gain traction due to its promise of simplicity and the sheer number of available icons.
It currently includes 1,800 icons in SVG or PNG formats and the website allows you to add icons to a live "collection" after which you can download all your selections at once.
Lightning BuilderLightning Builder is a free website mockup and wireframes builder that includes galleries of common components you can choose from. It requires signing up if you want to save your project and design multiple pages.
The builder boasts hundreds of components that can be customized and the entire experience of the builder’s UI is fairly smooth.
Scroll BtweenScroll Btween is sort of like a cross between an animation library and a parallax script. It allows you to 'tween' any CSS value for any element on the page relative to its position in the viewport.
There are lots of demos you can try out showing a diverse number of ways you can utilize it in your projects.
Text CleanerText Cleaner is an all-in-one text formatting tool that lets you deal with whitespace and special characters using various settings.
Paste in your text, then choose what you’d like to do — remove leading and trailing space, replace tabs with spaces, convert multiple spaces to single, remove non-ASCII characters, strip emojis, and lots more.
uiverseuiverse is a repository of community-built HTML and CSS components, free for personal and commercial use.
It currently includes more than 640 components in various categories including buttons, custom checkboxes, toggles, cards, loading animations, and inputs.
FonosterFonoster is an open-source alternative to Twilio, the popular communication API platform.
Fonoster also has its own pricing plan, with a modest free tier, but because it’s open-source, you have the option to host it yourself with no extra cost outside of your own infrastructure.
ZagZag is a library of framework-agnostic UI components that currently houses 20+ interactive components including a popover, slider, accordion, combobox, and lots more.
Each of the components can be easily integrated with React, Vue, or Solid.js, with info in the docs on how you can deal with each framework.
Allinone.toolsAllinone.tools is probably one of the largest collections of online utilities that I’ve come across. This includes tools for image manipulation and conversion, PDF tools, various text and list formatting options, CSS and JS minifiers and beautifiers, and lots more.
It also includes tools for carrying out various encryption-related tasks like encoding, decoding, decrypting, and so forth.
Martian MonoMartian Mono is the only font that made this list, and it’s a nice one. It’s a monospaced version of another font called Martian Grotesk, hence it’s useful for coders.
This one consists of a variable font and 28 styles ranging from condensed to semi-wide and thin to extra-bold.
AnimatiSSAnimatiSS is a collection of unique CSS animations, similar to other popular animation libraries that allow you to add animations to elements on the page using a class name.
This library includes animations under 10 style categories and you even adjust the duration of each one directly on the page.
HTMLShellHTMLShell is a simple tool you can use for generating a copy-and-paste customized HTML template for a landing page or other project. The tool includes a number of toggles that allow you to add or remove various elements in the <head>
section.
For example, you can include or exclude a CSS reset, Twitter social cards, viewport meta tag, Google Analytics, and lots more.
FormationFormation is a React and TypeScript-based library of 20+ components that feature accessible features like focus management and color contrast out-of-the-box.
The collection includes buttons, cards, modals, overlays, spinners, toast notifications, tooltips, and lots more.
Vanta.jsVanta.js is a JavaScript library that produces WebGL-based effects that are cool to look at but should rarely be used, if ever, due to potential performance problems. This tool allows you to create custom animated backgrounds with a few lines of code.
The website allows you to customize different background effects directly on the page using an interactive sidebar, after which you can grab the code.
Kumiko CreatorKumiko Creator made the list this year probably mostly due to curiosity clicks rather than practicality. This online generator allows you to upload your own photo to convert it to generate customized kumiko patterns.
As the site explains, the term "kumiko" refers to "an ancient Japanese woodworking technique, which involves slotting together many tiny pieces into a lattice."
AtomicoAtomico is a micro-library for creating UI components, similar to projects like React and Vue, with a React-inspired syntax. It’s compatible with those libraries as well as Svelte and Angular.
The library has scored high on performance tests, uses virtual DOM, props, hooks, and more making it an easy solution to transition to if you’re already familiar with other popular solutions.
mmmotifmmmotif is one of the many useful online generators created by Sébastien Noël. This one allows you to create and customize SVG-based 3D-like isomorphic patterns for use as backgrounds.
The generator allows you to select a base shape for the background, after which you can adjust angle, scale, skew, and the position of the repeated pattern.
DevToysDevToys is a native offline Windows app that’s a "Swiss army knife" for developers. It includes 20+ tools are useful for various development-related tasks.
There are decoders, encoders, converters, hash generation, text diffing, and much more.
mediaquery.stylemediaquery.style is a simple little online code resource for quickly copying and pasting the most commonly used CSS media query snippets.
The website allows you to grab code for mobile first media queries, range queries, light/dark, reduced-motion, hover/pointer, orientation, and print.
LyraLyra is an open-source, dependency-free, full-featured full-text search engine for your site that can run in any JavaScript runtime including the browser, server, React Native, and more. It’s written in TypeScript and boasts strong performance in comparison to its competitors.
You can try it out directly on the page, which has enabled movie search engine on the page that allows you to search for recent film titles.
W3.CSSW3.CSS is one of the few tools on this list that isn’t actually new. Apparently it’s been around in some form since 2015 but I only discovered it this past year. It’s a modern, responsive, mobile-first CSS framework similar to Bootstrap, made by the team at W3Schools.
Although W3Schools has received criticism over the years, they remain a popular resource for web developers and everyone seems to love their easy-to-digest documentation. This framework is also well documented and includes 50+ components and various tools and utilities.
AnimatizeAnimatize is a unique interactive animation builder that allows you to create simple CSS animations by dragging your mouse over a scene on the page.
Upload a background along with a character image, then drag the character over the background to define your animation. The site will generate the CSS code for you using data URIs for the images.
MetaliCSSMetaliCSS is a JavaScript library that allows you to add a sleek CSS-based metallic look to elements on the page.
After adding the library, use the class metallicss
after which you can make any customizations directly in the CSS using three custom properties.
Paper Prototype CSS is CSS framework that mimics paper prototyping, sort of like a handdrawn look but a little more ransom-note-ish, with the help of two informal-looking free fonts.
It’s inspired by other hand-drawn CSS frameworks and the home page shows you all the HTML elements in the Paper Prototype style so you can see how they each look.
Ava MakerCustom avatars always seem to be a popular trend. Ava Maker is an avatar generator that allows you to choose from a variety of styles to build your own custom avatar.
You can customize the hair, skin color, eyebrows, eyes, mouth, clothing, and more, before exporting the SVG or PNG file.
HopeUIHopeUI is a production-ready open-source admin dashboard based on Bootstrap 5. You can choose a version for Vue, React, Laravel, Tailwind, Figma, and more.
It offers 400+ components, 60+ menu styles, 20+ special plugins, and includes light/dark modes and RTL support.
Amigo CSSAmigo CSS is described as a "simple, custom-first and intuitive CSS framework" that’s tailored for beginners, building on some of the ideas present in other frameworks.
The framework encourages a custom class (which isn’t required) along with up to a maximum of seven utility classes per element. For the full details, check out the philosophy section of the website.
Hibiki HTMLHibiki HTML is an HTML-friendly JavaScript framework geared towards all levels of JavaScript developers and doesn’t require any boilerplate setup, scaffolding, build tools, and so on.
The main website includes an interactive tutorial and playground you can use to get accustomed to the syntax. Hibiki’s features are based around the use of the HTML <template>
element, with concepts similar to popular libraries like Turbo and Hotwire.
Rich text editors that you can embed in a page or app are plenty and Stylo is the one in this category that made this year’s list. It has no dependencies, is framework agnostic, and can be customized to your app’s needs.
Try it out live on the page, it works smoothly and seems to be very user friendly.
CSS.GUICSS.GUI is a free visual tool that’s CSS-based, to help you build components that you can export as HTML/CSS code.
You can do just about anything you can do with raw CSS, including adding pseudo-elements, and you also get a tree view of the page’s HTML that allows you to easily select elements before customizing them.
Simple.cssSimple.css is yet another option for a classless CSS framework that provides an attractive starting point for your HTML elements.
Similar to other classless frameworks, this one’s goal is to go beyond merely a reset or normalizer. It makes your elements look good by default without adding any extra bloat associated with larger frameworks.
Reasonable ColorsReasonable Colors is open-source color system for building color palettes that are both accessible and attractive. This means you get high-contrast combinations that are designer-friendly.
Select a color, after which you can choose your colors from the shades included for each. Choosing accessible colors is possible as long as there is a shade difference of 2 between the selections.
PlainAdminPlainAdmin is a Bootstrap 5 admin dashboard template that includes 100+ UI components and 15+ HTML pages.
There’s also a paid version with more components and features but the free version alone is a decent starting point for a solid dashboard template.
MeshyMeshy is a "mesh" gradient generator that includes a gallery of predefined mesh gradients, along with the ability to customize any of the gradient options. You can also randomize the "meshing" effect for any of the selected gradients, each of which uses 4 colors.
Any of the gradients can be downloaded in PNG format and the file can be sized to up to 3000x3000px for high resolution exports.
Bunny FontsBunny Fonts is a platform of open-source fonts that works as a drop-in replacement for Google Fonts. It has the same API format but with a focus on privacy and being GDPR-friendly.
The site works similarly to the Google Fonts UI and it currently includes over 1,400 fonts, about the same as the number available on Google Fonts.
StylifyStylify is a library that generates optimized CSS based on syntax that’s identical to real CSS.
The idea here is that your "classes" are actually CSS property/value pairs, then the library will generate the equivalent styles. This way you don’t have to learn the syntax of the framework, you simply use regular CSS.
WandaWanda is a design system from the team at Wonderflow that includes 40+ components along with a gallery of 360+ vector symbols.
The Wanda system has a focus on accessibility and the concept of form follows function. Both of these contribute to a set of UI components that are usable and accessible to as wide an audience as possible.
Symbols to CopySymbols to Copy is a one-stop resource of copy/paste symbols to include in your websites, apps, or documentation.
Includes arrows, currency symbols, fractions, Latin and Greek letters, Math symbols, punctuation and more. I also like that you can click any symbol to get the full code info including Unicode, HTML entity, and more.
Open UIOpen UI isn’t exactly a framework but an industry standard set of guidelines to define how developers can style and extend built-in web UI controls, such as checkboxes, radio buttons, select dropdowns, and so on.
The idea behind the project is to create initiatives that help developers avoid having to reinvent the wheel in the library and framework space, but instead to encourage these components to move to universal standards that everyone can benefit from.
California Design SystemThe California Design System is a resource for developers and designers building digital products in the state of California, in the U.S.A.
The design system includes principles, style guides, and components with guidelines on use, all for the benefit of filling the needs of customer-facing state websites in California.
Bamboo CSSBamboo CSS is yet another option for a classless CSS framework. This one’s source code is written in SCSS and also borrows from a few CSS normalizers.
It includes support for light and dark themes based on user OS settings and includes a small set of CSS variables that you can use for theming, if needed.
IT ToolsIT Tools is another all-in-one resource that includes dozens of tools and utilities useful for web developers and programmers.
This one includes crypto-based tools, conversion tools, miscellaneous web tools, image tools, and text tools. All the tools in this one are well-designed and easy to use.
QwikQwik is described as an "HTML-first" framework with performance at its core due to a small JavaScript footprint and on-demand component loading.
The docs include links to production sites built with the framework that have high page performance scores, demonstrating the real-world benefits.
SiimpleSiimple is a CSS toolkit, or framework, that includes lots of modules, components, and helpers. The components come with a default minimal design that can easily be customized.
The name is based on its simplicity of use by means of official presets and the ability to easily customize colors, fonts, sizes, design accents, and lots more.
Lorem FacesLorem Faces is a gallery of free AI-generated photos of people that you can use for mockups and as design placeholders.
You can choose square, rounded, or circular photos and color, greyscale, or sepia for the image’s tone.
HTTP Status DogsHTTP Status Dogs is a gallery of HTTP status codes each matched with an appropriate dog photo. You can use these for your own site or apps status messages if you like.
There have been similar projects like this one in the past, but this one includes a few more status codes and many of the matching photos are quite humourous!
Clay.cssClay.css is a CSS utility for adding a claymorphism style to page elements. This is definitely not going to be used on many projects, but the effect is nice and might come in handy in a children’s project or something else that requires a fun and informal look.
You can include and customize the styles using a utility class, CSS variables, or by means of a Sass mixin.
john-doejohn-doe is a concept for a one-page website that was first put out in late 2020, but I only came across it this past year. The idea behind this one is the use of CSS’s :target
pseudo-class, which allows you to display different page content based on hash URLs (e.g. #home
, #about
, #contact
, etc) and IDs on page elements.
The only drawback to this method is the fact that search engines generally don’t recognize hash-based URL changes as separate pages. So this is a novelty-type thing that you probably wouldn’t use on anything important.
MdashMdash is a UI library of components that’s 100% standards-based. The components are all based on HTML and Custom Elements and thus can work along with any web framework.
Many of the components are simply pure HTML with some sensible defaults, while others are a little more interactive depending on the component.
Preline UIPreline UI is an open-source set of ready-to-use components built on Tailwind CSS. It’s a huge collection of more than 250 components compatible with React and Vue or a plain HTML + Tailwind project.
All components include dark mode and there are base components (buttons, lists, etc.), navigation components, form components, overlays, and tables. All components are beautifully designed and the docs are quite extensive in demonstrating the different ways the components can be used.
UI ButtonsUI Buttons is a unique collection of 100 buttons that feature styles and hover effects you may not have seen elsewhere.
The CSS for each button is easy to grab and you can easily customize the colors and overall look while maintaining the interactive effects.
AgnosticUIAgnosticUI is a set of framework-agnostic UI components that work in React, Vue, Angular, Svelte, and vanilla JavaScript.
The components allow customization and theming via CSS custom properties and include about 30 common UI patterns along with guidelines for use in the different frameworks or as pure CSS.
TimelineJSTimelineJS is an open-source JavaScript library and spreadsheet tool that allows you to embed an interactive timeline component on a web page.
You can build the timeline based on data from a Google Sheet template that the site provides, then you can generate the timeline by entering the URL to your sheet. There’s also the option to use JSON as the data source, which would be more privacy-friendly.
JSON CrackAnd finally, JSON Crack was the most popular tool of year according to the unique click stats in my newsletter. This was originally referred to as "JSON Visio" and it’s a visualization tool and formatter for your JSON data.
Paste your data into the editor and the tool will display it in an easy-to-read flowchart format that you can customize or even embed on your own pages. There’s a search feature to find data in large files and there’s an associated VS Code extension.
What Was Your Favourite Tool of 2022?I hope you enjoyed this list of the most popular tools of the past year! While you may not be able to use all of these in your projects today, maybe these will inspire you to build something yourself in 2023. This certainly gives us a good idea of the kinds of things developers today are looking for.
I’m always on the lookout for the latest in tools for front-end developers, so feel free to post your favourites in the comments and you can subscribe to my newsletter if you want to keep up with the latest every week!
In recent years, the web development community has rightfully spread the message widely that images are often the largest resource on any given web page. While many developers spend time optimizing other areas of a web page’s performance, reducing the size of images can have a bigger impact on performance than all other areas combined.
You might already know that Smashing Magazine has published the book Image Optimization by Addy Osmani, which covers this topic in full detail. But consider this post a compliment to the book, as this will focus purely on different tools available for reducing the size of images.
WebUtils Bulk Image CompressWebUtils Bulk Image Compress allows you to compress images and convert them to WebP, JPG, PNG, AVIF, and JXL. There doesn’t seem to be an indication of limitations on file size or the number of files, but it is a slow process if you try to do a bulk conversion. You can also adjust quality and size, and everything is done client-side.
Compressor.io lets you optimize JPEG, PNG, SVG, GIF, and WebP using lossy or lossless compression up to 10MB per file. If you want to customize the compression or use larger files, you’ll have to get the Premium plan. The compression, in this case, seems to be on the server side, so you’ll get much faster results.
Imagecompresser.com lets you upload up to 10 files simultaneously and supports PNG, JPEG, WebP, JPG, and GIF formats. There doesn’t seem to be any limit on the file size per image, so this would likely work well for large files of 10 or fewer.
AnyWebP is specifically for converting images in WebP format, and you can output to JPEG, PNG, or ICO. You can customize by file size or quality. You also have the option to convert just about any file format (TIFF, PSD, BMP, etc.) to WebP. This tool also offers offline native apps for Mac and Windows that let you bulk convert. In any case, none of the files get uploaded to the server.
Compressimage.io allows fully offline image optimization with no limits on file size or the number of files. The only limitation this seems to have is that you can only compress JPEG and PNG. The custom options allow you to adjust the compression level, image size, and if you want to convert to WebP. You can also add a custom suffix to the file name.
JPEG.rocks, as the name suggests, is a privacy-friendly JPEG image optimizer, fully client-side and open-source. There doesn’t seem to be a limit to the file size or number of files, and you can customize the output file quality.
Compressor.js is quite different from the other tools in this list. It includes about a dozen different settings that let you customize the image quality, size, mime type, and more. The only big limitation is that you have to do one file at a time. So this wouldn’t be a good option for bulk resizing but is effective for specific optimizations you want to perform on a particular image.
Squoosh is designed by the Chrome Labs team. The web app is limited to a single image, but it includes several options for reducing size, color palette, choosing a compression method, compression quality level, along with a slew of other advanced settings. The engine that powers this tool is also available as an API or CLI for bulk processing.
SVGOMG is specifically for reducing the size of SVG graphics. It’s a GUI for SVGO, a Node.js-based tool. SVG optimizers are useful because many programs that produce SVG include redundant and useless info in the SVG code that produces the image.
Optimizilla uses lossy compression to reduce the size of JPEG, GIF, and PNG images. You can upload up to 20 images, and you have the option to customize the compression level and quality for each of the images before downloading.
Shrink Me lets you bulk optimize JPEG, PNG, WebP, or SVG images with no discernible quality loss. There is no limit on the number of files or file sizes, but larger files will mean a slower compression process.
JPEG Stripper optimizes JPEG files by stripping out unnecessary data. Allows only a single image uploaded at a time, so this would only be useful for a few images in JPEG format.
Shrink Media lets you optimize PNG, JPEG, and WebP images up to 5000x5000 resolution, and it’s also available as a mobile app for iOS or Android. Use the interactive sliders to change the quality level and the photo dimensions. You can also paste a URL to an image, but this tool only allows you to optimize one image at a time.
OptimizeImages lets you reduce the size of SVG, PNG, JPEG, WebP, GIF, and AVIF while also giving you the option to convert to WebP or AVIF. Optimize up to 30 images and choose a compression quality option (recommended, medium, or ultra).
ImagesTool.com includes a number of different image manipulation tools. You can adjust the size, convert, compress images, and more. Supports JPEG, WebP, SVG, GIF, and APNG. All done client-side, and you can choose between lossless and custom compression. No limit to the number of files you can optimize, and you can also upload by folder or paste in your images.
AVPress is a little different as it is specifically for optimizing video files and GIF animations. It allows a single video or GIF to be processed at once and includes several customizations and output settings you can apply to your chosen file.
AVIF Converter lets you convert just about any image format to AVIF, a next-generation file format that purports to have better compression than WebP, JPEG, PNG, and GIF. This app doesn’t seem to have any limitations on the number of files or file sizes, but note that the AVIF format is not yet supported in all modern browsers.
TinyPNG is an older tool that optimizes WebP, PNG, or JPEG files. You can upload up to 20 at a time and up to 5MB in size each.
The tools I’ve listed up to this point are good options for manual batch processing or optimizing a few images at a time. But in the context of a large project, you’ll want to consider using different tools that are designed to be incorporated as part of an ongoing workflow or build process. Here are some options you can consider:
Depending on what build tool or task runner you’re using, the aforementioned imagemin is likely available as a plugin for your tool of choice. Here are some imagemin plugins for different build tools:
Finally, if you’re building native apps that require image processing and optimizing on the fly, here are some C programming language options:
You might want to check out other tools and resources for image optimization. These don’t necessarily fall under the above categories, but they might fit one of your specific use cases.
If you know of another tool for optimizing different image formats for web, native, or mobile apps, feel free to let us know in the comments. In the meantime, I hope this list of tools will suffice to provide whatever you need to fill your image optimization requirements.
In January, Madison Kanna asked her Twitter followers:
What are the languages/tech you’re excited to learn or learn more deeply this year?
— Madison Kanna (@Madisonkanna) January 3, 2022
mine: typescript, next.js, react, graphql, solidity, node
My answer was easy: HTML. And I wasn’t being sarcastic or mocking in the least. Sure, I pretty much know which tags to use in which instances and how to keep my HTML mostly semantic and accessible.
But there is a whole bunch of lesser-used attributes that I was sure I’d forgotten about, and probably a whole bunch of attributes I didn’t even know existed. This post is the result of my research, and I hope you’ll find some of these useful to you, as you build HTML pages in the coming months.
Theenterkeyhint
Attribute For Virtual Keyboards
The enterkeyhint
attribute is a global attribute that can be applied to form controls or elements that have contenteditable
set to true
. This attribute assists users on mobile devices that use a virtual on-screen keyboard.
<input type="text" enterkeyhint="done">
enterkeyhint
accepts one of seven possible values that will determine what the user sees on his 'enter' key:
enter
,done
,go
,next
,previous
,search
,send
.You can see how these “hints” can be useful for the user. Is the user progressing through a series of actions? Are they submitting info? Are they saving a setting? Depending on what they’re doing, you can customize the hint to match your app’s needs.
You can try this one out by visiting the CodePen demo below on a mobile device.
And just to emphasize, this attribute doesn’t accept custom values; the value needs to be one of the seven shown above. An unrecognized value will just default to whatever the device’s default text is for the enter key.
Thetitle
Attribute On Stylesheets
This one was brand new to me when doing research for this article and might be the most interesting one in this list. As a bit of background, in case you didn’t know, Firefox has an option that lets you select which style sheet you want to use when viewing a page. Normally, this feature displays two options: “Basic Page Style” and “No Style”, as shown in the image below on my Windows machine.
This lets you quickly test how a page will look when styles are disabled, and it also allows you to view the page with any alternate stylesheets.
The alternate stylesheet feature is enabled with two attributes: The title
attribute and rel=alternate
applied to a <link>
element, as shown in the code below:
<link href="main.css" rel="stylesheet" title="Default">
<link href="contrast.css" rel="alternate stylesheet" title="High Contrast">
<link href="readable.css" rel="alternate stylesheet" title="Readable">
In this case, my “default” styles will apply automatically, but the alternate stylesheets will only apply if I select them using Firefox’s “Page Style” option. You can try out the above example by visiting the following CodePen, using Firefox or another compatible browser:
As mentioned, this feature works in Firefox, but I wasn’t able to get it to work in any Chromium-based browser. MDN’s article on alternate stylesheets says it can be enabled in other browsers using an extension, but I couldn’t find an active extension that does this.
Thecite
Attribute For The <blockquote>
And <q>
Elements
I’m sure you use the <blockquote>
element pretty regularly. You can use it plainly without an attribute, but you also have the option to use the cite
attribute. Here’s an example that quotes the MDN article that describes using cite
on <blockquote>
:
<blockquote cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote#attr-cite">
A URL that designates a source document or message for the information quoted. This attribute is intended to point to information explaining the context or the reference for the quote.
</blockquote>
Since my blockquote above is from the MDN article that explains what cite
does, I’ve set the URL that points to the page as the cite
value.
You can see how this is useful, because it wraps up the quote and the source of the quote in one element. But note this further explanation in the HTML spec:
User agents may allow users to follow such citation links, but they are primarily intended for private use (e.g., by server-side scripts collecting statistics about a site’s use of quotations), not for readers.
And naturally, the same concepts apply to use of cite
on the <q>
element, which is used for inline quotations.
Ordered lists using the <ol>
element are used often. Some lesser known features that allow you to customize the behaviour of the numbering that appears in such a list are:
reversed
attribute, to number the items in reverse order (high to low instead of the default low to high);start
attribute, to define what number to start from;type
attribute, to define whether to use numbers, letters, or Roman numerals;value
attribute, to specify a custom number on a specific list item.As you can see, ordered lists are a lot more flexible with plain HTML than you might normally be accustomed to.
The reversed
attribute is an interesting one, because it doesn’t actually reverse the contents of the list itself; it only reverses the numbers next to each list item.
<ol reversed>
<li>List item...</li>
<li>List item...</li>
<li>List item...</li>
</ol>
The CodePen demo below adds some JavaScript, so you can interactively toggle the reversed
attribute.
See the Pen Reverse Ordered Lists with HTML [forked] by Louis Lazaris.
Notice, that the list itself stays the same, but the numbers change. Keep that in mind if you’re looking for a way to reverse the contents. That’s something you would do with JavaScript, CSS, or directly in the HTML source.
Above, I also mentioned three other attributes. Let’s incorporate those into the list to see how they can be used:
<ol reversed start="20" type="1">
<li>Typee: A Peep at Polynesian Life (1846)</li>
<li>Omoo: A Narrative of Adventures in the South Seas (1847)</li>
<li>Mardi: and a Voyage Thither (1849)</li>
<li>Redburn: His First Voyage (1849)</li>
<li value="100">White-Jacket; or, The World in a Man-of-War (1850)</li>
<li>Moby-Dick; or, The Whale (1851)</li>
<li>Pierre; or, The Ambiguities (1852)</li>
<li>Isle of the Cross (1853 unpublished, and now lost)</li>
</ol>
Note, the type
and start
attributes that have been added as well as the value
attribute on an individual list item. The type
attribute accepts one of the five single-character values (a
, A
, i
, I
, 1
) representing the numbering type.
Try it using the following interactive demo:
See the Pen Reverse Ordered Lists with start, type, and value Attributes [forked] by Louis Lazaris.
Use the radio buttons to select one of the five values for the type
attribute. Then try reversing the list using the Toggle Reversed
button. As you can see, there is a ton of possibilities beyond the default behaviour of ordered lists!
download
Attribute For The <a>
Element
As ubiquitous as links are on the web, it’s always nice to have an attribute that makes links even more powerful. The download
attribute was added to the spec a number of years ago, and it allows you to specify that when a link is clicked, it should be downloaded rather than visited.
<a href="/example.pdf" download>Download File</a>
With no value, the download
attribute forces the linked page to be downloaded. Alternatively, you can provide a value which the browser uses as the suggested file name for the downloaded resource.
<a href="/example.pdf" download="my-download.pdf">Download File</a>
As a bonus trick involving this attribute, you can combine this feature with some JavaScript to create a way for the user to download content they create themselves. I covered it a little bit previously in this post, and you can try it out by using the demo below.
See the Pen The download Attribute Combined with a Data URI + JavaScript to Let the User Download Custom HTML [forked] by Louis Lazaris.
Thedecoding
Attribute For The <img>
Element
This is another one that was brand new to me when researching this article — and it seems to be fairly new in the spec. Adding the decoding
attribute to an image element provides an image decoding hint to the browser.
<img src="/images/example.png" alt="Example" decoding="async">
This attribute is similar to using the async
attribute on scripts. The time it takes to load the image doesn’t change, but the manner in which its “decoded” (and thus its content becomes visible in the viewport) is determined by the decoding
attribute.
Values are:
sync
async
auto
If you’re curious about the concept of decoding images, the spec has a good explanation that’s not too difficult to follow.
Theloading
Attribute For The <iframe>
Element
As you probably already know, image elements can now include a loading
attribute that puts lazy loading into the browser as a feature, something we’ve been doing for years with JavaScript solutions. But don’t forget that the loading
attribute can also be used on <iframe>
elements:
<iframe src="/page.html" width="300" height="250" loading="lazy">
As with images, the loading
attribute accepts either a value of eager
(the default browser behaviour) or lazy
, which defers loading of the iframe’s contents until the iframe is about to enter the viewport. The only down-side to this attribute is the fact that its use on iframes is not supported in Firefox (though, Firefox does support loading
on images).
form
Attribute for Form Fields
In most cases, you’re going to nest your form inputs and controls inside a <form>
element. But if your app or layout requires something a little different, you have the option to put a form input anywhere you want and associate it with any <form>
element — even one that’s not the element’s parent.
<form id="myForm" action="/form.php">
<input id="name">
<button type="submit">
</form>
<input type="email" form="myForm">
As you can see above, the email <input>
that’s outside the form has the form
attribute set to myForm
, which is set to the same value as the id
of the form. You can associate a form control (including the submit
button) with any form in a document by using this attribute and the form’s id.
You can try this out using this demo page. The form submits using a GET request, so you can see the values submitted in the URL’s query string. On that page, the “comments” box is outside the <form>
element.
The only complaint I have with this attribute is that it probably should have been given a more unique name, maybe something like “formowner”. Nonetheless, it’s a useful one to remember, should your design or layout require a parent-less form field.
Thecite
And datetime
Attributes For Deletions/Insertions
I’ve already mentioned cite
when dealing with blockquotes, but this attribute can also be used with deletions and insertions marked up with the <del>
and <ins>
elements. Additionally, both elements can include a datetime
attribute.
<del
cite="https://bugzilla.mozilla.org/show_bug.cgi?id=1620467"
datetime="2020-07-23"
>Firefox doesn't support CSS's standard <code>appearance</code> property, so you can only use it prefixed.</del>
<ins
cite="https://bugzilla.mozilla.org/show_bug.cgi?id=1620467"
datetime="2020-07-23"
>The <code>appearance</code> property, previously only available prefixed in Firefox, can now be used in all modern browers unprefixed.</ins>
For each element, here’s what the two attributes represent:
cite
datetime
In my case, I’m using the example of some text, describing a CSS property that required a vendor prefix in Firefox. This might be an old blog post. Once the prefixes were removed, I could delete
the old text and insert
the new text using the <del>
and <ins>
elements. I can then use the cite
attribute to reference the bug report where the problem was resolved.
label
Attribute for the <optgroup>
Element
Finally, this last one is a bit of a golden oldie, but because it doesn’t get used too often, maybe you didn’t even know it existed. This one is a combination of an element along with an attribute.
If you have a long list of items included in the options for a <select>
drop-down, you can group the options into visible categories using the <optgroup>
element along with its associated label
attribute:
<select>
<option>--Your Favourite Animal--</option>
<optgroup label="Birds">
<option>Blue Jay</option>
<option>Cardinal</option>
<option>Hummingbird</option>
</optgroup>
<optgroup label="Sea Creatures">
<option>Shark</option>
<option>Clownfish</option>
<option>Whale</option>
</optgroup>
<optgroup label="Mammals">
<option>Lion</option>
<option>Squirrel</option>
<option>Quokka</option>
</optgroup>
</select>
You can try out an example by using the following CodePen:
See the Pen Using the label Attribute with optgroup Elements [forked] by Louis Lazaris.
Notice, each <optgroup>
has a label
attribute that defines a heading for each group — but the headings can’t be selected. As a bonus tip, you can also use the disabled
attribute on an <optgroup>
to disable all the options in that section of the <select>
drop-down.
imagesizes
and imagesrcset
Attributes for Preloading Responsive Images
This is another pair of attributes that were new to me when researching this article, and both of them are relatively new in the spec as well.
Both of these attributes can be defined along with rel=preload
and as
on the <link>
element, as follows:
<link rel="preload"
as="image"
imagesrcset="images/example-480.png 480w,
images/example-800.png 800w,
images/example.png 2000w"
imagesizes="(max-width: 600px) 480px,
(max-width: 1000px) 800px,
1000px"
src="images/example.png"
alt="Example Image">
Use of rel=preload
here informs the browser that we want the indicated resources to load in priority, so they’re not blocked by things like scripts and stylesheets. The as
attribute specifies the type of content requested.
You can preload regular images by using the href
attribute along with preload
and as
. But on top of that, you can use the imagesrcset
and imagesizes
attributes, as I’ve done in the code above.
This allows you to preload the correct image, depending on the size of the viewport or other media features you’ve specified in the imagesizes
attribute.
In addition to the attributes I’ve already described and demonstrated in detail, there are some others you might want to look into that I’ll just mention briefly here:
crossorigin
attribute which can apply to multiple elements, including <audio>
, <img>
, <link>
, <script>
, and <video>
, providing support for cross-origin resource sharing (CORS);title
attribute for <dfn>
and <abbr>
;disablepictureinpicture
attribute for the <video>
element;integrity
attribute for scripts, which helps the browser verify that the resource hasn’t been improperly manipulated;disabled
attribute for the <fieldset>
element, to easily disable multiple form elements simultaneously;multiple
attribute for email and file inputs.If you’ve used any of the attributes mentioned in this article, or if you know of another HTML feature that you’ve personally benefited from using in one of your projects, feel free to let me know in the comments.
Many modern programmers, including front-end and full-stack developers, work daily with the command line. Even those who are relatively new to web development are picking up command-line skills early and finding practical tools and utilities to enhance their productivity in the terminal.
This post presents a categorized list of many command-line apps I’ve personally discovered over the past few years. Some of them are relatively new, others have been around for a while. So I hope something in this roundup will interest you and help you get stuff done when working in the terminal.
You can jump to a category using the navigation below:
This section features terminals, multiplexers, console emulators, mobile terminals, and command-line workspaces that you can use to replace the default terminal app on your system.
tmux
tmux
is a popular terminal multiplexer for Unix-like operating systems that lets you easily switch among several programs in a single terminal, with the ability to “detach” a session (while still running in the background) or “reattach” it to a different terminal.
iTerm2
iTerm2
, the successor to iTerm, is a replacement for your Terminal on macOS that includes features like split panes, robust search, autocomplete, instant replay, along with a whole slew of configuration options.
Mosh is a remote terminal app (or mobile shell) for interactive SSH usage that includes several useful features for those who need to do terminal-based tasks over weak WiFi, cellular networks, or other less-reliable connections.
Zellij is a terminal workspace that has the base functionality of a terminal multiplexer (similar to tmux) but includes features that allow users to extend it and create a personalized environment via panes/tabs and plugins.
Hyper is an Electron-based terminal app for Mac, Windows, or Linux that’s built with web technologies (HTML/CSS/JS). Includes dozens of themes and plugins and is built on speed and stability.
cmder
cmder
is a portable console emulator for Windows that was built due to the lack of a good option in this area for Windows users.
a-Shell is an iOS app that offers a ‘terminal in your pocket’ with files/directory control, compatibility with Apple Shortcuts, multiple windows, and lots more.
Eternal Terminal is another remote terminal app inspired by other similar, popular projects.
Ten Hands is a terminal app for Mac, Linux, and Windows that is billed as the simplest way to organize and run command-line tasks, useful for those who run similar daily tasks on multiple projects.
eDEX-UI is a fullscreen, cross-platform terminal emulator and system monitor heavily inspired by science fiction movie UIs, in particular, the Tron: Legacy film.
Tabby, formerly “Terminus”, is a customizable cross-platform terminal app for local shells, SSH, serial, and Telnet connections that includes support for features like split panes, smart tabs, customizable hotkeys, and lots more.
Fish Shell is another option for a command-line shell for Linux, macOS, and Windows that includes auto-suggest, tab completions, 24-bit color, web-based configuration, syntax highlighting, among other practical features.
Once you’ve got your primary workspace, you’ll want to enhance it with various tools, utilities, themes, and so forth. This section includes some useful tools to make your terminal experience more enjoyable.
Oh My Zsh is an open-source, community-driven framework for managing your configuration for Z Shell (or Zsh, a popular Unix shell). It comes bundled with thousands of helpful functions, helpers, 300+ plugins, 140+ themes, and more. Works best on macOS or Linux, but can also be used on Windows using something like Cygwin or WSL2.
Fig adds VSCode-style autocomplete to your existing terminal and includes support for existing CLI tools like Git, npm, Kubernetes, Docker, AWS, Google Cloud, and more.
fzf
fzf
is a fast, portable, fuzzy finder for the command line that lets you run fuzzy search queries with a comprehensive feature set.
Shell History (not free) is a macOS app that integrates with Bash, Zsh, or Fish and allows you to easily backup and sync via iCloud and organize your shell history in “notebooks”.
htop
htop
is an interactive process viewer, originally Linux-only but now cross-platform, that aims to improve on the Linux top
command by providing extra features when viewing running processes.
GitHub CLI, in case you missed it, is the official cross-platform command-line interface for GitHub, bringing pull requests, issues, and other GitHub-related tasks to your terminal.
Streamhut lets you share your terminal in real-time without installing anything. Simply run one of two commands (depending on your setup), useful for live terminal sessions in team collabs, interviews, or teaching.
icdiff
icdiff
is a terminal-based file diff tool that makes good use of colors to present diffs in a more practical, visual manner.
>\_TerminalSplash
TerminalSplash
, as the name suggests, is like Unsplash, but for terminal themes. Choose from more than 200 user-submitted themes or submit your own.
Terminalizer is a customizable and cross-platform terminal recorder that lets you record terminal sessions then share them as animated GIFs or via a web player.
Asciinema is another popular option for terminal recording and sharing, but not available for Windows. The cool thing about this one is that the recorded output is not a video but a plain text animation of the terminal session, meaning you can select and copy/paste items from recordings.
gtop
gtop
is another enhancement on the top
command that provides a system monitoring dashboard for your terminal. Require Node.js and includes partial support on Windows.
DevDash
DevDash
is a highly configurable terminal dashboard for developers and creators. You can customize it to display information from sources like Google Analytics, GitHub, Feedly, shell command output, and more.
ora
tiny-care-terminal
theme.sh
Some numerous libraries and frameworks allow you to build and maintain your own command-line apps and utilities. Below you’ll find a few of those for Bash, JavaScript, and more.
Command And Conquer, also called cac, is a lightweight JavaScript framework for building command-line apps. For example, it’s been used to build several Node.js-based scaffolding tools.
zx
zx
is a popular alternative to Bash from engineers at Google that allows you to write command-line apps using JavaScript with an easy-to-use API that allows you to call executables and get their output, handle errors, and more.
present
present
is a Markdown-based presentation tool for the terminal that includes colors and effects and allows you to play pre-recorded playable code blocks as slides.
Bach is a Bash testing framework that can be used to test scripts that contain dangerous commands like rm -rf /
and also includes APIs (e.g. @mock
, @ignore
, @mockallto
, etc.) to mock commands.
CLUI
CLUI
is a JavaScript API with utilities to allow you to build command-line interfaces with context-aware autocomplete into your apps (i.e. terminal-like applications that users interact with).
ShellCheck
ShellCheck
is a shell extension to help you find bugs in your shell scripts.
Bashō
import
Bash Infinity
Finally, this category puts together a small sampling of command-line utilities and programs that help with various productivity-related tasks like keeping stuff organized, sharing files, and more.
Dash Dash is an online documentation site that presents the Unix man pages (i.e. manual pages) in a more palatable format, to help those less familiar with the terminal learn to use the command line.
nb
nb
is a command-line tool with features that include local web note‑taking, bookmarking, archiving, and encryption. Storage is in plain text, includes Git-based versioning, wiki-style linking, color themes, and lots more.
Rclone
Rclone
is an open-source command-line program that allows you to manage files on 40+ cloud storage services (Amazon S3, Dropbox, Google Drive, Azure, etc.). It includes cloud equivalents for familiar Unix commands and other features.
navi
navi
is an interactive cheatsheet tool for your terminal. In addition to other features, you can browse through cheatsheet repositories, import cheatsheets, or add your own.
Taskbook is a fast command-line tool that lets you organize tasks, boards, and notes in your terminal, with features like search/filter, custom storage location, and a simple and user-friendly syntax.
Project Explorer is a CLI tool that lets you build a tree visualization of any project. This would come in handy when bringing on new team members or when inheriting a new project.
transfer.sh
transfer.sh
is a fast and easy-to-use app for sharing files via the command line. Includes support for services like Amazon S3, Google Drive, Storj, and the local file system.
ack
goto
bashupload
copyfiles
As mentioned, this wasn’t meant to be an exhaustive list, but merely a big collection of relevant command-line apps and utilities that I’ve personally come across in the past few years.
If you’ve built something yourself or if there’s one you use regularly that supercharges your terminal experience, feel free to drop it in the comments!
In complex web apps, DOM changes can be frequent. As a result, there are instances where your app might need to respond to a specific change to the DOM.
For some time, the accepted way to look for changes to the DOM was by means of a feature called Mutation Events, which is now deprecated. The W3C-approved replacement for Mutation Events is the MutationObserver API, which is what I’ll be discussing in detail in this article.
A number of older articles and references discuss why the old feature was replaced, so I won’t go into detail on that here (besides the fact that I wouldn’t be able to do it justice). The MutationObserver
API has near complete browser support, so we can use it safely in most — if not all — projects, should the need arise.
A MutationObserver
can be used in a number of different ways, which I’ll cover in detail in the rest of this article, but the basic syntax for a MutationObserver
looks like this:
let observer = new MutationObserver(callback);
function callback (mutations) {
// do something here
}
observer.observe(targetNode, observerOptions);
The first line creates a new MutationObserver
using the MutationObserver()
constructor. The argument passed into the constructor is a callback function that will be called on each DOM change that qualifies.
The way to determine what qualifies for a particular observer is by means of the final line in the above code. On that line, I’m using the observe()
method of the MutationObserver
to begin observing. You can compare this to something like addEventListener()
. As soon as you attach a listener, the page will ‘listen’ for the specified event. Similarly, when you start observing, the page will begin ‘observing’ for the specified MutationObserver
.
The observe()
method takes two arguments: The target, which should be the node or node tree on which to observe for changes; and an options object, which is a MutationObserverInit
object that allows you to define the configuration for the observer.
The final key basic feature of a MutationObserver
is the disconnect()
method. This allows you to stop observing for the specified changes, and it looks like this:
observer.disconnect();
As mentioned, the observe()
method of a MutationObserver
requires a second argument that specifies the options to describe the MutationObserver
. Here’s how the options object would look with all possible property/value pairs included:
let options = {
childList: true,
attributes: true,
characterData: false,
subtree: false,
attributeFilter: ['one', 'two'],
attributeOldValue: false,
characterDataOldValue: false
};
When setting up the MutationObserver
options, it’s not necessary to include all these lines. I’m including these simply for reference purposes, so you can see what options are available and what types of values they can take. As you can see, all except one are Boolean.
In order for a MutationObserver
to work, at least one of childList
, attributes
, or characterData
needs to be set to true
, otherwise an error will be thrown. The other four properties work in conjunction with one of those three (more on this later).
So far I’ve merely glossed over the syntax to give you an overview. The best way to consider how each of these features works is by providing code examples and live demos that incorporate the different options. So that’s what I’ll do for the rest of this article.
The first and simplest MutationObserver
you can initiate is one that looks for child nodes of a specified node (usually an element) to be added or removed. For my example, I’m going to create an unordered list in my HTML, and I want to know whenever a child node is added or removed from this list element.
The HTML for the list looks like this:
<ul id="myList" class="list">
<li>Apples</li>
<li>Oranges</li>
<li>Bananas</li>
<li class="child">Peaches</li>
</ul>
The JavaScript for my MutationObserver
includes the following:
let mList = document.getElementById('myList'),
options = {
childList: true
},
observer = new MutationObserver(mCallback);
function mCallback(mutations) {
for (let mutation of mutations) {
if (mutation.type === 'childList') {
console.log('Mutation Detected: A child node has been added or removed.');
}
}
}
observer.observe(mList, options);
This is only part of the code. For brevity, I’m showing the most important sections that deal with the MutationObserver
API itself.
Notice how I’m looping through the mutations
argument, which is a MutationRecord
object that has a number of different properties. In this case, I’m reading the type
property and logging a message indicating that the browser has detected a mutation that qualifies. Also, notice how I’m passing the mList
element (a reference to my HTML list) as the targeted element (i.e. the element on which I want to observe for changes).
Use the buttons to start and stop the MutationObserver
. The log messages help clarify what’s happening. Comments in the code also provide some explanation.
Note a few important points here:
mCallback
, to illustrate that you can name it whatever you want) will fire each time a successful mutation is detected and after the observe()
method is executed.childList
, so it makes sense to look for this one when looping through the MutationRecord. Looking for any other type in this instance would do nothing (the other types will be used in subsequent demos).childList
, I can add or remove a text node from the targeted element and this too would qualify. So it doesn’t have to be an element that’s added or removed.Another common type of mutation that you might want to track is when an attribute on a specified element changes. In the next interactive demo, I’m going to observe for changes to attributes on a paragraph element.
let mPar = document.getElementById('myParagraph'),
options = {
attributes: true
},
observer = new MutationObserver(mCallback);
function mCallback (mutations) {
for (let mutation of mutations) {
if (mutation.type === 'attributes') {
// Do something here...
}
}
}
observer.observe(mPar, options);
Again, I’ve abbreviated the code for clarity, but the important parts are:
options
object is using the attributes
property, set to true
to tell the MutationObserver
that I want to look for changes to the targeted element’s attributes.attributes
, the only one that qualifies in this case.attributeName
property of the mutation
object, which allows me to find out which attribute was changed.In this example, a button is used to toggle a class name on the targeted HTML element. The callback function in the mutation observer is triggered every time the class is added or removed.
Another change you might want to look for in your app is mutations to character data; that is, changes to a specific text node. This is done by setting the characterData
property to true
in the options
object. Here’s the code:
let options = {
characterData: true
},
observer = new MutationObserver(mCallback);
function mCallback(mutations) {
for (let mutation of mutations) {
if (mutation.type === 'characterData') {
// Do something here...
}
}
}
Notice again the type
being looked for in the callback function is characterData
.
In this example, I’m looking for changes to a specific text node, which I target via element.childNodes[0]
. This is a little hacky but it will do for this example. The text is user-editable via the contenteditable
attribute on a paragraph element.
If you’ve fiddled around with contenteditable
, then you might be aware that there are keyboard shortcuts that allow for rich text editing. For example, CTRL-B makes text bold, CTRL-I makes text italic, and so forth. This will break up the text node into multiple text nodes, so you’ll notice the MutationObserver
will stop responding unless you edit the text that’s still considered part of the original node.
I should also point out that if you delete all the text, the MutationObserver
will no longer trigger the callback. I’m assuming this happens because once the text node disappears, the target element is no longer in existence. To combat this, my demo stops observing when the text is removed, although things do get a little sticky when you use rich text shortcuts.
But don’t worry, later in this article, I’ll discuss a better way to use the characterData
option without having to deal with as many of these quirks.
Earlier I showed you how to observe for changes to attributes on a specified element. In that case, although the demo triggers a class name change, I could have changed any attribute on the specified element. But what if I want to observe changes to one or more specific attributes while ignoring the others?
I can do that using the optional attributeFilter
property in the option
object. Here’s an example:
let options = {
attributes: true,
attributeFilter: ['hidden', 'contenteditable', 'data-par']
},
observer = new MutationObserver(mCallback);
function mCallback (mutations) {
for (let mutation of mutations) {
if (mutation.type === 'attributes') {
// Do something here...
}
}
}
As shown above, the attributeFilter
property accepts an array of specific attributes that I want to monitor. In this example, the MutationObserver
will trigger the callback each time one or more of the hidden
, contenteditable
, or data-par
attributes is modified.
Again I’m targeting a specific paragraph element. Notice the select drop down that chooses which attribute will be changed. The draggable
attribute is the only one that won’t qualify since I didn’t specify that one in my options.
Notice in the code that I’m again using the attributeName
property of the MutationRecord
object to log which attribute was changed. And of course, as with the other demos, the MutationObserver
won’t start monitoring for changes until the “start” button is clicked.
One other thing I should point out here is that I don’t need to set the attributes
value to true
in this case; it’s implied due to attributesFilter
being set to true. That’s why my options object could look as follows, and it would work the same:
let options = {
attributeFilter: ['hidden', 'contenteditable', 'data-par']
}
On the other hand, if I explicitly set attributes
to false
along with an attributeFilter
array, it wouldn’t work because the false
value would take precedence and the filter option would be ignored.
So far when setting up each MutationObserver
, I’ve only been dealing with the targeted element itself and, in the case of childList
, the element’s immediate children. But there certainly could be a case where I might want to observe for changes to one of the following:
All of the above can be achieved using the subtree
property of the options object.
First, let’s look for changes to an element’s child nodes, even if they’re not immediate children. I can alter my options object to look like this:
options = {
childList: true,
subtree: true
}
Everything else in the code is more or less the same as the previous childList
example, along with some extra markup and buttons.
Here there are two lists, one nested inside the other. When the MutationObserver
is started, the callback will trigger for changes to either list. But if I were to change the subtree
property back to false
(the default when it’s not present), the callback would not execute when the nested list is modified.
Here’s another example, this time using subtree
with attributes
and attributeFilter
. This allows me to observe for changes to attributes not only on the target element but also on the attributes of any child elements of the target element:
options = {
attributes: true,
attributeFilter: ['hidden', 'contenteditable', 'data-par'],
subtree: true
}
This is similar to the previous attributes demo, but this time I’ve set up two different select elements. The first one modifies attributes on the targeted paragraph element while the other one modifies attributes on a child element inside the paragraph.
Again, if you were to set the subtree
option back to false
(or remove it), the second toggle button would not trigger the MutationObserver
callback. And, of course, I could omit attributeFilter
altogether, and the MutationObserver
would look for changes to any attributes in the subtree rather than the specified ones.
Remember in the earlier characterData
demo, there were some problems with the targeted node disappearing and then the MutationObserver
no longer working. While there are ways to get around that, it’s easier to target an element directly rather than a text node, then use the subtree
property to specify that I want all the character data inside that element, no matter how deeply nested it is, to trigger the MutationObserver
callback.
My options in this case would look like this:
options = {
characterData: true,
subtree: true
}
After you start the observer, try using CTRL-B and CTRL-I to format the editable text. You’ll notice this works much more effectively than the previous characterData
example. In this case, the broken up child nodes don’t affect the observer because we’re observing all nodes inside the targeted node, instead of a single text node.
Often when observing for changes to the DOM, you’ll want to take note of the old values and possibly store them or use them elsewhere. This can be done using a few different properties in the options
object.
First, let’s try logging out the old attribute value after it’s changed. Here’s how my options will look along with my callback:
options = {
attributes: true,
attributeOldValue: true
}
function mCallback (mutations) {
for (let mutation of mutations) {
if (mutation.type === 'attributes') {
// Do something here...
}
}
}
Notice the use of the attributeName
and oldValue
properties of the MutationRecord
object. Try the demo by entering different values in the text field. Notice how the log updates to reflect the previous value that was stored.
Similarly, here’s how my options would look if I want to log old character data:
options = {
characterData: true,
subtree: true,
characterDataOldValue: true
}
Notice the log messages indicate the previous value. Things do get a little wonky when you add HTML via rich text commands to the mix. I’m not sure what the correct behavior is supposed to be in that case but it is more straightforward if the only thing inside the element is a single text node.
Another method of the MutationObserver
object that I haven’t mentioned yet is takeRecords()
. This method allows you to more or less intercept the mutations that are detected before they are processed by the callback function.
I can use this feature using a line like this:
let myRecords = observer.takeRecords();
This stores a list of the DOM changes in the specified variable. In my demo, I’m executing this command as soon as the button that modifies the DOM is clicked. Notice that the start and add/remove buttons don’t log anything. This is because, as mentioned, I’m intercepting the DOM changes before they are processed by the callback.
Notice, however, what I’m doing in the event listener that stops the observer:
btnStop.addEventListener('click', function () {
observer.disconnect();
if (myRecords) {
console.log(`${myRecords[0].target} was changed using the ${myRecords[0].type} option.`);
}
}, false);
As you can see, after stopping the observer using observer.disconnect()
, I’m accessing the mutation record that was intercepted and I’m logging the target element as well as the type of mutation that was recorded. If I had been observing for multiple types of changes then the stored record would have more than one item in it, each with its own type.
When a mutation record is intercepted in this way by calling takeRecords()
, the queue of mutations that would normally be sent to the callback function is emptied. So if for some reason you need to intercept these records before they’re processed, takeRecords()
would come in handy.
Note that if I’m looking for mutations on two different nodes on the page, I can do so using the same observer. This means after I call the constructor, I can execute the observe()
method for as many elements as I want.
Thus, after this line:
observer = new MutationObserver(mCallback);
I can then have multiple observe()
calls with different elements as the first argument:
observer.observe(mList, options);
observer.observe(mList2, options);
Start the observer, then try the add/remove buttons for both lists. The only catch here is that if you hit one of the “stop” buttons, the observer will stop observing for both lists, not just the one it’s targeting.
One last thing I’ll point out is that a MutationObserver
will continue to observe for changes to a specified node even after that node has been removed from its parent element.
For example, try out the following demo:
This is another example that uses childList
to monitor for changes to the child elements of a target element. Notice the button that disconnects the sub-list, which is the one being observed. Click the “Start…” button, then click the “Move…” button to move the nested list. Even after the list is removed from its parent, the MutationObserver
continues to observe for the specified changes. Not a major surprise that this happens, but it’s something to keep in mind.
That covers just about all the primary features of the MutationObserver
API. I hope this deep dive has been useful for you to get familiar with this standard. As mentioned, browser support is strong and you can read more about this API on MDN’s pages.
I’ve put all the demos for this article into a CodePen collection, should you want to have an easy place to mess around with the demos.