Building a reusable frontend stack for Iguana Solutions#

In short#

When I joined Iguana Solutions, the company had a several web projects in the pipeline, but little to no design and frontend development experience. I helped select a set of technologies and methodologies that would fit the company's culture and goals, while also learning a lot about builing Single Page Applications in the process.

The client#

Iguana Solutions is a full fledged hosting provider, offering consulting, DevOps solutions, managed cloud services and security audits. The company's customers include recognize groups and brands like Deezer, Easybourse, Canal+, H&M, among others.

The problems#

When I joined the company had many software ideas to further serve its clients, but not a lot of experience in web development. Members of the engineering team could build internal dashboards to monitor the client's projects, but nothing that could be used by clients or partners.

The first step was to interview the CTO and team members to learn about their tech habits and tastes, the resources available, and select a set of frontend technologies that could fit.

It became clear rapidly what we were going to build would require a big step up in visual design, interactivity, state management, and overal quality.

The solutions#

My directives from the CTO for the frontend technical stack were:

The frontend library#

I had worked with React (pre hooks era), Vue 2 and Angular 1 in the past, but wasn't very interested in them or their more recent versions for different reasons:

In the end I picked Svelte, for the followintg reasons:

In the end, Svelte proved to be a good pick and was never a hindrance in the projects. Its data stores were particularly suited for the different jobs we did, which often required syncing a lot of data from different places.

Styling#

To allow a rapid iteration of styles in our projects and still ensure a coherence in styles, I decided to use a mix between several methodologies:

I picked Tailwind CSS for the config for the design tokens and the utility classes, and kept its naming conventions, so anyone joining the projects could use the Tailwind docs and get up to speed. The base stylesheet was made with native CSS and the @apply tailwind function to fetch design tokens.

You might have wondered why not create a JavaScript component for each of the HTML elements? To make it short: because it was too much work, clashed with our iteration process, and did not benefit us. Except if they have entirely different functionalities that justified their isolation ; or if they come from or are built for a general purpose agnostic design system (ex: Material Design by Google) ; single HTML elements wrapped inside a JS component, just for styling purposes, are over-engineering.

Put simply: I decided we should bet on HTML and CSS, and extend them with JavaScript through our scoped components when needed.

Visual design#

Unfortunately the designs of the projects I worked on are still under an NDA and cannot be shown here. Without going into specifics, I can share the directions I took with the guidance of my leads.

First, I made a good use of color, transitions, SVG and CSS animations through the projects to create a feeling of playfulness and accessibility for our users. The goal was to find a balance between the austerity of technical tools and the more shiny dashboards managers and directors enjoy.

I also created drag and drop user experiences to allow non-technical users to interact with the content of some of our projects. Other type of pages included multi-steps operations, interfaces with real time updates, etc.

Routing and data fetching#

Routing followed Sveltekit's conventions, one folder = one route. Even if the projects were all SPAs, I still followed the convention of using a layout.ts or page.ts file in each route to fetch data before rendering (this is usually used for server side rendering).

I decided to use this to unify our applications UI rendering. You can use an onMount() life cycle method in svelte pages and components, but it would have resulted in a lot of loading spinners, a spread of the API calls, and a harder management of state. Using the sveltekit convention also allowed me to recover the upper level fetched data in lower pages, using the parent fonction.

For example:

  1. / will check the session and make it available to subpages
  2. /org_id will fetch a list of projects linked to the org and make it available to subpages
  3. /org_id/project_id will fetch project details and make it available to subpages

By enforcing this rule, jumping between projects did not require re-learning anything.

State management#

In single page applications, the state of the application is stored in memory, a hard refresh resets it, so it needs to be reproductable from the APIs.

Most of the projects' states were thought as state machines, and used Svelte stores heavily instead of passing props from a parent to nested components. A change of state from one of the API endpoint, or from the user, created a chain reaction that would change other states, allowing the apps to show what is necessary in each page (texts, popups, images, redirects, etc.).

Stores were organized this way:

  1. Writable stores were a mirror of each API data endpoint. They served as a source of truth, and were updated when the user changed something (a copy was stored to compare them and indicate unsaved changes in the UI). Their content could directly be sent through a POST/PUT call. They were called core stores.
  2. Derived stores subscribed to one or several core stores, modified their data to match the needs of the user interface, and sent it to the view. Svelte automatically updated the derived stores when a core store changed, which was an immense productivity boost.

This way, I achieved a one-way data flow: core reflects data, derived transforms core, the UI presents derived, the user modifies the UI, which updates the core, and repeat.

AWS Services#

The projects we created were all AWS centric. I learned about the following services, wrote reusable libraries interfacing with the AWS SDK V3 for our projects, as well as infrastructure as code templates in Cloudformation.

Lessons learned#


Initially published: Wed, 05 Jun 2024 00:00:00 UTC
Last modification: Fri, 08 Aug 2025 11:40:50 UTC