back to writings
Writing

Behind This Site

A look at the ideas, tools, and small decisions behind my portfolio, from file-based MDX to the details I keep refining.

Maruf Hossain6 min read

A portfolio is supposed to show the finished work. Mine kept becoming a project of its own.

Every time I added something—a project card, a writing page, a better way to browse—I learned a little more about what I wanted this corner of the internet to be. It slowly moved away from a polished online résumé and toward something more useful: a record of what I am building, learning, and changing my mind about.

That is why I call it Maruf's Build Log.

This post is the tour behind it: not just the technologies involved, but the decisions that made them worth keeping.

A Build Log, Not a Brochure

The first version of a portfolio is usually straightforward: a short introduction, a list of projects, and a contact link. That works, but it leaves out the part I find most interesting—the thinking between the starting point and the final screenshot.

I wanted the site to hold a few different kinds of work without making them feel disconnected. The homepage gives the quick version. Projects show what I have built. Writings give me enough room to explain an idea, a failure, or a lesson properly. The development log sits somewhere in between and records work that is still taking shape.

Keeping those parts together makes the site feel less like an archive of completed things and more like an ongoing notebook.

Next.js as the Frame

The site runs on Next.js with the App Router, React, and TypeScript. It is more framework than a small portfolio strictly needs, but it gives me one consistent place for static pages, dynamic writing routes, metadata, server actions, and image optimization.

Most of the site can be rendered without much client-side JavaScript. I use client components where interaction earns its place—search, theme switching, forms, and a few bits of motion—but articles and project content stay simple.

TypeScript has been especially useful as the site has grown. Project data, writing metadata, form inputs, and reusable components all have an expected shape. A portfolio does not have the complexity of a large product, but it is still easy for small inconsistencies to accumulate when the content and interface evolve together.

The styling is built with Tailwind CSS and a small set of shared design tokens. I use it less as a shortcut for decoration and more as a constraint: the same spacing, colors, borders, and type treatments should appear everywhere unless there is a reason for them not to.

Writing Without a CMS

The writing system is deliberately boring. Every article is an MDX file in the repository.

text
content/
  behind-this-site.mdx
  cors-error-and-problem-solving.mdx
  cricket-and-system-design.mdx
  ...

Each file starts with a small block of frontmatter for the title, summary, date, category, and tags. The rest is ordinary Markdown, with the option to use a React component when an article needs something more expressive.

On the server, gray-matter separates the frontmatter from the body. The site calculates reading time, sorts posts by date, and creates a page for each slug. next-mdx-remote renders the content, while a small set of custom components keeps headings, images, links, callouts, and code blocks consistent with the rest of the site.

The table of contents is generated from the article headings. Related posts are chosen from shared tags and categories. Syntax highlighting, canonical metadata, structured data, and social previews are handled by the article template rather than repeated in every post.

My publishing workflow is therefore short:

  1. Create an MDX file.
  2. Add the frontmatter.
  3. Write and revise the article.
  4. Push the change.

There is no editor dashboard and no database to keep in sync. Git holds the drafts and their history, and the writing lives beside the code that presents it. For a site maintained by one person, that is a feature.

Designing for the Work

The visual direction is intentionally quiet: a narrow reading column, a neutral palette, generous space, and typography doing most of the work. The site supports light and dark themes, but both use the same hierarchy rather than behaving like separate designs.

I have tried louder versions. They were fun for a moment, but the interface started competing with the projects and writing. The current design is closer to an editorial notebook. Cards create enough structure to scan, monospace labels provide a technical rhythm, and motion is saved for moments where it helps the page feel responsive.

That restraint has taken more iteration than the decorative versions did. A quiet interface makes small problems obvious: a heading that wraps badly, metadata with too much contrast, a card that sits a few pixels out of rhythm, or a paragraph that becomes tiring to read. Most design changes to this site are small because small changes are what the design exposes.

Images are kept with the project whenever possible and rendered through Next.js image optimization. The site can serve modern formats such as WebP and AVIF, but the more important rule is simpler: an image should explain something or show the work, not fill an empty rectangle.

The Small Pieces Behind the Pages

There is a little more machinery around the content, although I try to keep it proportional to the site.

The contact form uses a server action, validates input with Zod, and sends messages through Resend. My résumé is served through Vercel Blob, which lets the public URL stay stable even when the file changes. Search on the Writings and Projects pages happens in the browser because the collections are small enough that a search service would add complexity without adding value.

For analytics, I use PostHog to answer practical questions: which projects people open, whether writing search is useful, and where visitors choose to go. Vercel Speed Insights gives me a second view focused on how the site performs for real visitors. I am not interested in collecting data for its own sake; I want enough feedback to notice what is useful and what is getting in the way.

Deployment follows the same preference for few moving parts. The code lives on GitHub and the site is hosted on Vercel. A push creates a new deployment, so publishing an article and shipping a component change use the same workflow.

Still in Progress

This stack is not permanent. Next.js will change, libraries will come and go, and I will probably find parts of the site that deserve to be simpler. The goal is not to freeze the site around a list of fashionable tools.

The stable part is the system around them: content in portable files, reusable presentation, a short path from an idea to a published page, and as little maintenance as I can reasonably get away with.

There are still rough edges and unfinished experiments. That is appropriate. A build log should look cared for, but it should never look finished.

— Maruf

  • Next.js
  • MDX
  • TypeScript
  • Tailwind CSS
  • Web Design
Back to top