We've all been there. You have an idea, you start a side project with excitement, and then... it ends up in the GitHub graveyard, untouched for months.
This time, I was determined to break the cycle. I decided to build a tool that solved a set of real, frustrating problems I faced almost daily as a developer.
The Problem: A Lack of Control
My workflow often involves generating text with LLMs, which usually comes out as an unstructured mess. But the core frustration wasn't just the formatting; it was the lack of control in every step that followed.
- ** inflexible Previews:** When working with Arabic text, I couldn't find a live markdown preview that properly supported RTL.
- "One-Size-Fits-All" Styling: I wanted to change the preview's font size for readability or switch to a different font for a presentation, but most tools are static.
- Manual Formatting: The tedious process of manually adding headers, lists, and code blocks was a constant time sink.
I realized I didn't just want a markdown editor; I wanted a fully customizable, intelligent workstation. So, I decided to build it myself.
The Solution: Smart Markdown Pro
I'm excited to share Smart Markdown Pro, a local-first, AI-powered markdown editor built on a modern stack: Next.js (App Router), Tailwind CSS, and TypeScript.
It's open source, and I built it to be the tool I wish I had from the start.
The Features That Mattered to Me
1. Total Preview Customization
This was the core idea. I wanted a preview pane that adapted to my needs. In the settings, you can:
- Toggle RTL/LTR direction instantly.
- Adjust the base font size with a slider.
- Use any Google Font by pasting its link and CSS value. The app saves your previously used fonts for quick access.
2. AI-Powered Formatting
To solve the messy text problem, I integrated the OpenAI API. There's a single "Format with AI" button that takes your unstructured text and turns it into clean, well-formatted GFM. Because let's be honest, you can't ship an app in 2025 without a little AI, right? 😉
The backend is a simple Next.js API route that securely handles the API key and prompt.
// /src/app/api/format-with-ai/route.ts
const SYSTEM_PROMPT = `
You are an expert markdown formatter...
Your response must ONLY be the formatted markdown content.
`;
const completion = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'system', content: SYSTEM_PROMPT },
{ role: 'user', content: text },
],
// ...
});
3. Local-First File Management
I hate creating accounts for simple tools. So, I used Zustand
with its persist
middleware to save everything directly to the user's localStorage
. It supports creating, opening, searching, and deleting multiple documents, and it's incredibly fast.
// /src/lib/store/useDocumentStore.ts
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
// ...
export const useDocumentStore = create<DocumentState>()(
persist(
(set, get) => ({
// ... all the state and actions ...
}),
{
name: 'smart-markdown-pro-storage-v2',
}
)
);
4. High-Fidelity PDF Exports
This was the hardest technical challenge. Client-side libraries like html2canvas
kept failing because of modern CSS color formats (lab()
, oklch()
) used by Tailwind/Shadcn.
The solution? A serverless function using Puppeteer.
The frontend sends the preview's HTML to an API route. The backend launches a headless Chrome instance, injects the HTML and a minimal set of CSS, and uses Chrome's own print-to-PDF engine to generate a perfect PDF.
// /src/app/api/export/pdf/route.ts
import puppeteer from 'puppeteer-core';
import chromium from '@sparticuz/chromium'; // For serverless environments
// ...
browser = await puppeteer.launch({
args: chromium.args,
executablePath: await chromium.executablePath(),
headless: 'new',
});
const page = await browser.newPage();
await page.setContent(finalHtml, { waitUntil: 'networkidle0' });
const pdfBuffer = await page.pdf({ format: 'A4', printBackground: true });
// ...
Building What You Need is Rewarding
This project was a fantastic learning experience and a powerful reminder that the best projects often come from solving your own problems. It forces you to think through every detail and build something you genuinely want to use.
I'd love for you to check it out!
- Live App: https://smart-markdown-pro.vercel.app/
- GitHub Repo (Stars are super appreciated!): https://github.com/Abubakr-Alsheikh/smart-markdown-pro
What are some daily annoyances you've been tempted to turn into a side project? I'd love to hear about them in the comments
Top comments (4)
This tool will become 100% local-first should the developer integrate a local LLM such as Ollama.
Yes! This should be added to the list to switch between local and cloud LLM, for local runs and deployment runs.
How quickly do you think this can happen?
I worked with Ollama before, so it will take no time to add it.