PasteKit‑Style JSON/YAML Formatter

Format JSON, YAML & SQL privately

Welcome to another official UVF IT guide! In this quick‑fire tutorial we’ll build a minimal clone of PasteKit – a tiny web app that lets you paste JSON or YAML, formats it nicely, and returns the result instantly. No accounts, no cloud storage, just pure local processing.

We’ll use Node.js with Express and the open‑source js-yaml library, store snippets in an in‑memory array (so you can see the data flow), and run everything on your laptop in under 45 minutes.

Prerequisites & Gotchas

Architecture Overview
LOCAL RUNTIME HTTP API module import Express Server Node.js Static UI HTML/JS In‑memory Store JS Module
1

Phase 1: Scaffold the project

We start by creating a fresh npm project and pulling in the tiny set of libraries we need: Express for the HTTP server and js-yaml for YAML parsing/serialization. Then we lay out a simple folder structure – src for server code and public for the static UI files. This gives us a clean base to add features later.

All commands are run from the terminal in the project root. After the setup you’ll have a package.json ready, the dependencies installed, and empty folders where our code will live.

mkdir pastekit-clone && cd pastekit-clone
npm init -y
npm install express js-yaml
mkdir -p src public
cat > src/index.js <<'EOF'
// entry point – will be filled in later
EOF
2

Phase 2: Data model (in‑memory store)

The store module is a tiny in‑memory database that keeps each snippet in an array and hands out a monotonically increasing numeric ID. It exposes three helper functions – addSnippet, getSnippet, and listSnippets – which the API layer will call later. Because everything lives in RAM, the data disappears when the process stops, which is perfect for a demo clone.

Keeping the store isolated in its own file makes the rest of the code easier to test and reason about. Later phases will simply import this module and use its functions without caring how the data is kept.

store.js

// src/store.js
let nextId = 1;
const snippets = [];

/**
 * Add a new snippet and return its assigned ID.
 * @param {string} content – raw JSON/YAML string
 * @param {string} type – "json" or "yaml"
 */
function addSnippet(content, type) {
  const record = { id: nextId++, content, type, created: new Date() };
  snippets.push(record);
  return record.id;
}

/** Retrieve a snippet by its numeric ID. */
function getSnippet(id) {
  return snippets.find(s => s.id === Number(id)) || null;
}

/** Return a shallow copy of all stored snippets. */
function listSnippets() {
  return snippets.slice();
}

module.exports = { addSnippet, getSnippet, listSnippets };
3

Phase 3: Core API & formatter

In this step we expose a /format endpoint that receives raw text, determines whether it is JSON or YAML, formats it nicely, and stores the result in memory for later retrieval. Detecting the format lets us apply the right pretty‑printer: JSON.stringify for JSON and js-yaml for YAML. The endpoint returns the formatted string so the UI can display it instantly.

We also serve static assets from a public folder so the UI can be loaded from the same server. Keeping everything in one Express app simplifies local development and mirrors how PasteKit bundles its backend and frontend.

server.js

const express = require('express');
const bodyParser = require('body-parser');
const yaml = require('js-yaml');
const app = express();
let lastResult = '';
app.use(bodyParser.text({type: '*/*'}));
app.use(express.static('public'));
function isJson(str){
  try{JSON.parse(str);return true;}catch(e){return false;}
}
app.post('/format', (req,res)=>{
  const raw = req.body;
  let formatted;
  if(isJson(raw)){
    formatted = JSON.stringify(JSON.parse(raw),null,2);
  }else{
    const obj = yaml.load(raw);
    formatted = yaml.dump(obj, {indent:2});
  }
  lastResult = formatted;
  res.send(formatted);
});
app.get('/last', (req,res)=>res.send(lastResult));
app.listen(3000,()=>console.log('Listening on 3000'));
4

Phase 4: Minimal UI

The UI is a single HTML page that lets users paste raw JSON or YAML, hit a button, and see the pretty output. A <textarea> captures the input, a button triggers a fetch POST to /format, and a <pre> element displays the response.

All JavaScript lives inline for simplicity; it serializes the textarea value, sends it, and writes the server’s response back to the page. This minimal interface is enough to verify the core formatting logic works end‑to‑end.

public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>PasteKit‑Style Formatter</title>
  <style>body{font-family:sans-serif;margin:2rem;}textarea{width:100%;height:150px;}</style>
</head>
<body>
  <h1>JSON/YAML Formatter</h1>
  <textarea id="input" placeholder="Paste JSON or YAML here"></textarea><br/>
  <button id="formatBtn">Format</button>
  <h2>Result</h2>
  <pre id="output"></pre>
  <script>
    document.getElementById('formatBtn').onclick=()=>{
      const txt=document.getElementById('input').value;
      fetch('/format',{method:'POST',body:txt})
        .then(r=>r.text())
        .then(data=>document.getElementById('output').textContent=data)
        .catch(err=>alert('Error: '+err));
    };
  </script>
</body>
</html>
5

Phase 5: Run & verify locally

Now start the server and open the UI in a browser. The Express app will listen on port 3000 and serve the static page from public/. Once the page loads, you can test formatting both JSON and YAML inputs.

If everything is wired correctly, the server logs “Listening on 3000”, the UI appears, and the formatted output shows up after clicking the button.

node server.js

Verifying the Stack

CheckCommand / Why it matters
Server starts without errorsRun node server.js and see Listening on 3000 in the console.
UI loads in browserOpen http://localhost:3000 and see the textarea and Format button.
JSON input formats prettilyPaste {"a":1,"b":2} and click Format; output shows indented JSON.
YAML input formats to pretty YAMLPaste a: 1\nb: 2 and click Format; output shows formatted YAML.

What’s Next?

You now have a working local formatter. To approach the full PasteKit experience, add clipboard‑auto‑paste, syntax highlighting (Prism.js), and persistent storage (SQLite or Postgres). Happy hacking!