DEV Community

Cover image for I Built a Simple Web Tool and Here's What Nobody Tells You About the Process
Ghazala Parveen
Ghazala Parveen

Posted on

I Built a Simple Web Tool and Here's What Nobody Tells You About the Process

I'm not a senior developer. I don't have a CS degree. But a few months ago, I shipped a working web tool that actual people use. And the journey from "I have an idea" to "it's live on a custom domain" taught me more than any tutorial ever did.
Let me walk you through what actually happened.

The Idea Was Stupidly Simple

I kept running into the same annoying problem — I wanted to save short videos from social media to watch offline. Not for reposting, not for any shady reason. Just so I could watch a cooking tutorial on a flight or send a funny clip to my mom on WhatsApp.

Every tool I found was either full of sketchy pop-up ads, asked for my login credentials (huge red flag), or just didn't work half the time.

So I thought — how hard can it be to build something that just takes a URL, fetches the video file, and lets you download it?
Turns out, it's both easier and harder than I expected.

The Tech Stack I Chose (And Why)

I kept it dead simple:

Frontend: HTML, CSS, vanilla JavaScript
Backend: Node.js with Express
Hosting: VPS with Nginx
Domain: Custom .com domain
Enter fullscreen mode Exit fullscreen mode

No React. No Next.js. No Tailwind. I know that sounds heretical in 2026, but hear me out — for a single-purpose tool, you don't need a framework. A clean HTML page with some JS fetch calls does the job perfectly.

The backend was where the real work happened. The flow is straightforward:

// Simplified version of the core logic
app.post('/api/fetch-video', async (req, res) => {
  const { url } = req.body;

  // Validate the URL
  if (!isValidURL(url)) {
    return res.status(400).json({ error: 'Invalid URL' });
  }

  // Fetch the page, parse the meta tags / video source
  const videoData = await extractVideoSource(url);

  // Return the direct video URL to the client
  res.json({ downloadUrl: videoData.src, quality: videoData.quality });
});
Enter fullscreen mode Exit fullscreen mode

The tricky part? The extractVideoSource function. Social media platforms don't just hand you the video file on a silver platter. You have to parse the page HTML, look through meta tags, and sometimes dig through embedded JSON in the page source.

Things That Broke (And What I Learned)

Lesson 1: APIs change without warning.

I built my first version using a specific pattern to extract video URLs. It worked perfectly for two weeks. Then one morning — everything broke. The platform had changed its page structure. No announcement, no changelog. Just broken.

I rewrote the parser three times in the first month. That's when I learned to build flexible parsing logic with multiple fallback methods:

async function extractVideoSource(url) {
  // Try method 1: Open Graph meta tags
  let result = await tryOGTags(url);
  if (result) return result;

  // Try method 2: Embedded JSON-LD data
  result = await tryJSONLD(url);
  if (result) return result;

  // Try method 3: Script tag parsing
  result = await tryScriptParsing(url);
  if (result) return result;

  throw new Error('Could not extract video source');
}
Enter fullscreen mode Exit fullscreen mode

Lesson 2: Error handling is not optional.

My first version had almost no error handling.

If something went wrong, the user got a blank screen or a cryptic error. I quickly learned that users don't read console logs. They need clear, human-readable messages.
Now every possible failure has a friendly message: "This link doesn't seem to contain a video," "The video might be private," or "Something went wrong on our end — try again in a minute."

Lesson 3: Rate limiting will save your server.

About a week after launch, someone (or some bot) started hitting my API hundreds of times per minute. My tiny VPS almost died. I added rate limiting the same day:

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 50, // limit each IP to 50 requests per window
  message: 'Too many requests. Please try again later.'
});

app.use('/api/', limiter);
Enter fullscreen mode Exit fullscreen mode

Should have done this from day one. Lesson learned.

The Things Tutorials Don't Teach You

DNS propagation is not instant.

I bought my domain, pointed it to my server, and then spent 6 hours wondering why it wasn't working. Turns out, DNS can take up to 48 hours to propagate. Nobody told me that.

SSL certificates matter more than you think.

Without HTTPS, browsers show a scary "Not Secure" warning. I used Let's Encrypt with Certbot — it's free, and setting it up with Nginx took me about 20 minutes after watching a tutorial.

Nobody will find your tool unless you tell them.

I spent weeks building it, launched it, and then got zero visitors for days. Turns out, "build it and they will come" is a lie. I had to learn basics of SEO — meta tags, page titles, descriptions, sitemap.xml, submitting to Google Search Console. This was a whole separate skill I didn't expect to need.

Your first users will find bugs you never imagined.

Someone tried to paste a URL with extra spaces. Someone else pasted a whole paragraph instead of a URL. Someone submitted an empty form 47 times. You learn to never trust user input.

What I'd Do Differently

If I started over today, I would:

Start with error handling and rate limiting from day one, not after things break

Add basic analytics (even just counting requests per day) so I know if anyone is actually using it

Write tests — I know, I know, everyone says this. But I didn't write a single test until something broke in production at 2 AM and I couldn't figure out what changed

Use environment variables from the start instead of hardcoding config values and then painfully refactoring later

The Result

The tool works. It's live at downreels.com and handles a few hundred requests daily. It's not going to make me rich. It's not going to impress anyone at a FAANG interview. But it solves a real problem, real people use it, and I built it from scratch.

That feeling of typing your domain into a browser and seeing something YOU built — I can't describe it. If you've shipped something, you know what I mean. If you haven't yet, I promise it's worth the frustration.

For Anyone Thinking About Building Their First Tool

Just start. Pick a problem you personally have. Keep the tech stack simple. Don't use a framework unless you actually need one. Ship something ugly that works, then make it pretty later.

The gap between "I'm learning to code" and "I built something people use" is smaller than you think. It's mostly just the willingness to deal with things breaking at 2 AM and not quitting.

Happy building.

Top comments (0)