Breathing New Life into a Legacy UI with Next.js 15 & Tailwind CSS v4

Abhi MuraliAbhi Murali
4 min read

My GSoC project involves rebuilding the SwitchMap-NG frontend by replacing its Flask-based UI with a modern React-based interface. The original UI was built using server-rendered HTML and the now-deprecated flask-table package, which limited interactivity and blocked backend upgrades. Instead of trying to patch the old system, the goal is to create a fresh, responsive, and maintainable frontend—while continuing to use the existing Flask backend and GraphQL API.

This project has been an exciting opportunity to explore modern tools like

  • Next.js 15.3.3 (with React 19 and the App Router)

  • Tailwind CSS v4 (with its new CSS-based theming)

  • GraphQL (for efficient and flexible data fetching)

  • TanStack Table (for dynamic tables)

  • next-themes (for dark/light mode support)

By combining these tools, the project aims to deliver a modern, high-performance UI that lays the groundwork for new features the SwitchMap community has been anticipating.


Getting Started with the Frontend

The first step was setting up a clean and minimal Next.js app with TypeScript, using the latest features available in Next.js 15. This included enabling the App Router and adding basic routing for the dashboard and device pages.

To integrate with the Flask backend, fetch() was used to query GraphQL endpoints. Additionally, Cross-Origin Resource Sharing (CORS) was enabled on the backend by adding flask_cors.CORS(app) to allow secure cross-origin requests.


Styling with Tailwind CSS v4

A notable enhancement involved upgrading to Tailwind CSS v4, which enables full configuration directly within CSS. This eliminates the need for a separate tailwind.config.js file by allowing all customizations to be defined in the global CSS:

@import "tailwindcss";
@theme {
  --color-bg: var(--bg-color);
  --color-text: var(--text-color);
  /* ... */
}
:root {
  --bg-color: #e6e6e6;
  --text-color: #081028;
  /* ... */
}
.dark {
  --bg-color: #081028;
  --text-color: #AEB9E1;
  /* ... */
}

This approach simplifies theme management and provides a more intuitive way to define design tokens. Additionally, integration with next-themes ensures persistent user theme preferences, automatically falling back to the system theme on first load, and is complemented by a toggle for switching between light and dark modes.


Building Interactive Tables with GraphQL

Replacing flask-table meant choosing a flexible table library that could handle pagination, filtering, and dynamic data. I went with TanStack Table, which integrates smoothly with React and provides fine-grained control over rendering.

GraphQL queries power all the data in these tables. Here's a simplified version of one query that fetches devices by zone:

const query = `
  query GetZoneDevices($id: ID!) {
    zone(id: $id) {
      devices {
        edges {
          node {
            hostname
            sysName
          }
        }
      }
    }
  }
`;

Debugging the Data Layer

Working with real-world data is rarely smooth. Several challenges came up during integration:

  • Some MAC address identifiers returned from one query didn’t match any records in related datasets.

  • Certain queries returned empty results, even when relevant data was present.

  • Key details like IP addresses, DNS names, and vendor information were missing or inconsistently linked.

These issues highlighted the importance of a well-designed schema. As part of the project, the schema and models will be updated to expose more complete and reliable data for the frontend.


Laying the Foundation for New Features

With the new stack in place, I can now start working on:

  • A Network Topology Graph using open-source libraries

  • Enhanced device and port detail views with real-time data

  • Better loading states and fallback UIs for GraphQL queries

  • Polishing the responsiveness, accessibility, and styling across the app


Takeaways

This project has been a deep dive into what it means to modernize a frontend:

  • Replacing legacy tools doesn’t mean rewriting everything—it means integrating new tools thoughtfully.

  • Next.js and Tailwind CSS v4 provide an excellent developer experience and future-facing architecture.

  • Collaborating with an existing backend requires understanding both client and server perspectives.

I’m excited to continue evolving this UI and sharing what I learn along the way. If you're tackling a similar modernization project, I hope this post helps you feel a little more confident stepping into the unknown.

Stay tuned for more updates!

0
Subscribe to my newsletter

Read articles from Abhi Murali directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Abhi Murali
Abhi Murali

A self-taught software engineer passionate about modern web development. I write about my learning journey, projects, and GSoC experiences using Next.js, React, Tailwind CSS, and GraphQL.