The framework everything runs on.
App Router with server components. The marketing pages and the dashboard are rendered on the server, so a page of scoring evidence arrives as HTML rather than as a spinner followed by three fetches.
Every company and open-source project Dice runs on, and what each one actually does here. A dependency nobody can explain the job of is a dependency worth removing, so this list is the whole list.
The framework everything runs on.
App Router with server components. The marketing pages and the dashboard are rendered on the server, so a page of scoring evidence arrives as HTML rather than as a spinner followed by three fetches.
The interactive layer.
Only what genuinely needs interaction ships JavaScript — the opportunity filters, the pipeline runner, the preview cards. Everything else stays a server component and costs the browser nothing.
Types on every boundary.
Scoring weights, database rows, and API responses share one set of types. Change how an opportunity is scored and the build fails, rather than a customer's ranked list quietly changing meaning.
The token layer and every style.
One set of tokens defines the palette, radii, and shadows for both themes. Nothing hardcodes a colour, which is why dark mode is a variable swap instead of a second stylesheet.
Hosting and the CDN in front of it.
Runs the rendered pages and caches them at the edge. Preview deployments mean a change to the scoring copy can be read in context before it reaches anyone.
Postgres, auth, and row-level security.
Every table is scoped to a workspace by a policy inside the database, not by a WHERE clause someone has to remember. A query that forgets the workspace returns nothing instead of returning someone else's opportunities.
The database underneath it.
Candidates, enrichments, opportunities, publishers, and contacts are genuinely relational, and ranking is a query over them. Keeping the evidence in a real database is what makes a result inspectable months later.
Runs the long jobs.
Discovery, enrichment, qualification, and contact discovery outlive any HTTP request. They run as durable tasks that survive a deploy and retry a flaky provider instead of losing an hour of work.
Fetches and reads the actual page.
Dice judges an article by its content rather than its title, which means something has to fetch the page and turn it into clean text first. This is the step most tools skip.
Reads the article and rates the fit.
Content relevance, placement suitability, and the competitor gap come from a model that has read the page. The weights that turn those into a score are ours, deterministic, and published on the home page.
Supplements contact discovery.
Public author bylines and contact pages come first. Hunter runs only after a page is qualified, so credits are never spent on a candidate that the hard checks were going to reject anyway.
Checkout and subscriptions.
Handles the paid trial and the monthly plan, and tells the app what someone is entitled to through a webhook. Access is derived from that, never from a flag set by hand.
Sends the transactional mail.
Sign-in links, receipts, and the notification that a pipeline run has finished. A plain API and sane deliverability defaults, which is what keeps a small sender out of the spam folder.
Connects a Google mailbox.
Outreach goes out from your own address, not from a shared pool. OAuth means the connection can be revoked from your Google account at any time, without going through us.
Connects an Outlook mailbox.
The same arrangement for Microsoft 365 and Outlook accounts, through MSAL. IMAP and SMTP remain available for everything neither provider covers.
The runtime.
Server rendering, the API routes, and the background tasks all run on it — one language across the request path and the pipeline.
Installs the dependencies.
Strict by default: a package you did not declare is a package you cannot import, which catches a whole class of “works on my machine” before it ships.
Validates what crosses a boundary.
Model output, webhook payloads, and request bodies are parsed rather than trusted. A malformed provider response fails at the edge with a readable error instead of becoming a null halfway through a pipeline run.
Runs the tests.
The scoring, ranking, and hard-check logic are pure functions with unit tests, so the numbers on this site can be derived from the same code that produces them in the product.
Keeps the codebase consistent.
Rules for React and Next.js specifically — the ones that catch a client component that did not need to be one, or a state update that will cascade.
Every icon on the site.
One consistent stroke weight across the marketing pages and the dashboard, tree-shaken so a page ships only the icons it draws.
One token layer, two themes. Every swatch below paints itself from the same custom property the app uses, so this page always shows the palette you are actually looking at.
--backgroundthe page, everywhere--foregroundbody text and headings--subtlealternating sections and hover fills--raisedcards and anything lifted off the page--mutedsecondary prose--faintlabels, captions, metadata--borderhairlines between things--border-strongthe edge of a card--primaryactions, links, and where you are--primary-subtletinted fills behind primary--successverified, complete, passing--warningaccept-all, needs a look--dangerrejected and failedSet in the system UI stack for everything readable, and in Pixelify Sans for the wordmark at the bottom of the page. Self-hosted, so no third party learns which pages you read.
Logos are each vendor’s own and belong to them. Their appearance here records what Dice is built with, not any endorsement by them.