React has been DMC’s JavaScript framework of choice for over 10 years. In recent years, we’ve been using it alongside Next.js to build maintainable, scalable, full-stack web applications. In this blog series, I’m going to demonstrate using React and Next.js to build a DBA dashboard, offering a variety of tools to spot and troubleshoot performance or reliability issues with a SQL Server instance.
I plan to use Better-Auth for authentication and Material UI as a UI component library, and of course, I’ll be using SQL Server (a.k.a. MSSQL). So, if you’d like to learn how to build a React app with Next.js, Better-Auth, Material UI, and MSSQL using Prisma ORM, I’m going to show you how to set it all up.
Scaffolding a Next.js App
The first step to building a Next.js app is to run the create-next-app CLI tool. First, make sure you’ve installed Node.js version 24 or later. Then, run npx create-next-app@latest the CLI tool and create the application. It presents us with the following options:

I recommend the following options:
- TypeScript – at DMC, we’ve used it for React applications since 2016 and have adopted it as a standard. TypeScript is a superset of JavaScript that adds strong typing so that, for example, you’ll get a compiler error if you try to assign an integer value to a string variable. Fully explaining TypeScript is outside of the scope of this article, but I strongly recommend using it for all React applications.
- ESLint – this is the gold standard linter for JavaScript/TypeScript, and you really can’t go wrong by choosing it.
- React Compiler – I have been very eager to try this out on a project ever since it was introduced to React. Among other things, this makes it so you don’t need to explicitly use the useMemo or useCallback hooks – the compiler will take care of those optimizations for you so that you can focus on building your app.
- src directory – this is a pretty standard setup for JavaScript/TypeScript applications.
- App Router – the alternative is Page Router, which is the legacy version of Next.js.
By default, the CLI tool gets us set up with a package-lock.json file, but I prefer to use Yarn as my package manager, so I like to delete that file and run yarn install. Then I keep the yarn.lock file in source control.
The app scaffolded by the CLI tool can be run locally with the command yarn dev. Doing so shows me a placeholder home page that looks like the following:

When I’m building a new app, the first thing I do is clear out all the scaffolded content, like that placeholder page and the accompanying CSS. Once I’ve finished that, layout.tsx file and page.tsx file scaffolded by the CLI looks like the following:
// layout.tsx
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "DBA Dashboard",
description:
"A dashboard UI for exploring the results from the SQL Server First Responder Kit stored procedures",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
// page.tsx
export default function Home() {
return (
<div>
<main>
<header>
<h1>DBA Dashboard</h1>
</header>
<p>
Welcome to the DBA Dashboard! There's not much here yet, but stay
tuned for updates as we build out the UI for exploring the results
from the SQL Server First Responder Kit stored procedures.
</p>
</main>
</div>
);
}
And here’s the resulting home page of our new Next.js app:

You may notice a little circular “N” button at the lower left corner – that’s a widget that Next.js gives us when running locally in dev mode. (TODO: Give more details about this, probably a link to documentation. This feature is new to me – apparently it’s called a “devIndicator”).
Configuring the Next.js App
At the start of a new project, I like to get off on the right foot with regard to linting. Our scaffolded app is set up for ESLint out of the box, so I can run yarn lint to check for violations, and there are quite a few!

These violations are coming from files that were created by the CLI tool – I didn’t write this code. Because of that, I’d like to ignore these files when doing lint checks – to do that, I can add the “types” folder to the eslint.config.mjs file:
import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";
const eslintConfig = defineConfig([
...nextVitals,
...nextTs,
// Override default ignores of eslint-config-next.
globalIgnores([
// Default ignores of eslint-config-next:
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
// Custom ignores:
"types/**",
]),
]);
export default eslintConfig;Now, if I run yarn lint again, it only raises one violation:

Looks like I forgot to use an HTML entity for that apostrophe in my hard-coded text. So I’ll just fix that:
// page.tsx
export default function Home() {
return (
<div>
<main>
<header>
<h1>DBA Dashboard</h1>
</header>
<p>
Welcome to the DBA Dashboard! There's not much here yet, but stay
tuned for updates as we build out the UI for exploring the results
from the SQL Server First Responder Kit stored procedures.
</p>
</main>
</div>
);
}
After fixing that, ESLint raises no violations, so now we’re officially starting with a squeaky-clean codebase!

In the next blog post, we’ll be adding a component library to our project: Material UI. A high-quality component library like Material UI makes it easy to build a professional-looking user interface for our dashboard.
Have an upcoming project? DMC can help you take the next step.
Take your project to the next level with engineering solutions from DMC. Learn more about our Application Development solutions or contact us to get started today!







