It was an incredibly busy June, as I had the chance to participate in the World’s Largest Hackathon . Through this, I gained first-hand experience with Vibe Coding —a term coined by Andrej Karpathy —which refers to coding with the support of LLMs in an interactive and exploratory manner.

I started the project using Bolt.new , set up my backend quickly with Supabase , and deployed the frontend seamlessly using Netlify . In this post, I’ll share how I took the project further by running bolt.diy locally—experimenting with different models through OpenRouter and deploying my own LLM-assisted text utility tool, TextForge.

One-Shot Challenge Entry: TextForge

For the hackathon’s One-Shot Challenge, I submitted TextForge —a multi-functional toolkit tailored for text and data manipulation. It’s a developer-focused playground for quickly cleaning, formatting, converting, and analyzing text.

After iterating on various prompts and refining the features, I settled on a version that delivered just the right blend of utility and user experience. You can try the hosted TextForge demo here .

Prerequiste: Cloning and Running bolt.diy Locally

bolt.diy is the open-source counterpart to bolt.new, giving you the freedom to self-host and configure your preferred LLMs for prompt generation and code synthesis.

Clone the Repository

git clone https://github.com/stackblitz-labs/bolt.diy.git
cd bolt.diy

Install Dependencies and Run

npm install -g pnpm
pnpm install
pnpm run dev

You should see the startup CLI confirming the dev server is active:

bolt-diy-startup

Then, navigate to your local instance, typically at http://localhost:5173:

bolt-diy-welcome-screen

To interface with different models, I configured bolt.diy to use OpenRouter —a flexible gateway that provides API access to a variety of leading LLMs including Anthropic Claude, GPT variants, Mistral, and more.

My One-Shot Prompt for TextForge

Here’s the prompt that I crafted to bootstrap the generation of TextForge. It serves as a specification for a multi-tool, developer-centric utility with robust UX/UI features and thoughtful tooling:

One-shot prompt
TextForge: The Ultimate Text & Data Manipulation Toolkit
A responsive, multi-tool web application designed for developers and writers to clean, format, convert, and generate text and data snippets efficiently.
1. Text Cleanup & Analysis
Features:
Whitespace & Lines: Remove extra spaces, remove all line breaks, convert to a single line.
Text Analysis: Live word count, character count, and line count.
Clear Input: A quick button to clear the text area.
Implementation:
Generated javascript
// Example React state and handler
const [input, setInput] = useState("");
const [output, setOutput] = useState("");

// Analysis is derived from input state
const wordCount = input.trim().split(/\s+/).filter(Boolean).length;
const charCount = input.length;

const handleCleanup = (action) => {
  let result = "";
  switch (action) {
    case "removeExtraSpaces":
      result = input.replace(/\s+/g, ' ').trim();
      break;
    case "removeLineBreaks":
      result = input.replace(/(\r\n|\n|\r)/gm, ' ');
      break;
    case "clear":
      setInput("");
      result = "";
      break;
    default:
      result = input;
  }
  setOutput(result);
};
Use code with caution.
JavaScript
2. Case Converter
Features:
Standard Cases: UPPERCASE, lowercase, Sentence case.
Programming Cases: camelCase, PascalCase, snake_case, kebab-case.
Instant conversion on button click.
Implementation:
Use a combination of native string methods and regular expressions for complex cases.
Generated javascript
// Example conversion logic
const toCamelCase = (str) => {
  return str.toLowerCase().replace(/([-_ ][a-z])/g, g => g.toUpperCase().replace(/[-_ ]/g, ''));
};

const toPascalCase = (str) => {
  const camel = toCamelCase(str);
  return camel.charAt(0).toUpperCase() + camel.slice(1);
};

const handleCaseChange = (caseType) => {
  let result = "";
  switch (caseType) {
    case "uppercase": result = input.toUpperCase(); break;
    case "camelCase": result = toCamelCase(input); break;
    // ... other cases
  }
  setOutput(result);
};
Use code with caution.
JavaScript
3. Code & Data Formatter
Features:
JSON Tools: Beautify (pretty-print) and Minify JSON.
Data Conversion: Convert delimited Key-Value pairs (e.g., name=John\nage=30) into a JSON object.
CSS Minifier: Strip comments and whitespace from CSS code.
Implementation:
Use native browser APIs and a lightweight library for CSS.
Generated javascript
// JSON Formatting
const formatJSON = (beautify = true) => {
  try {
    const jsonObj = JSON.parse(input);
    const space = beautify ? 2 : 0;
    setOutput(JSON.stringify(jsonObj, null, space));
  } catch (error) {
    setOutput("Error: Invalid JSON");
  }
};

// Key-Value to JSON
const convertKvToJson = () => {
  const lines = input.split('\n').filter(line => line.includes('='));
  const obj = lines.reduce((acc, line) => {
    const [key, ...valueParts] = line.split('=');
    acc[key.trim()] = valueParts.join('=').trim();
    return acc;
  }, {});
  setOutput(JSON.stringify(obj, null, 2));
};

// For CSS Minification, suggest a library like 'clean-css' if building with Node/bundler
// In a simple client-side app, a regex approach can be a starting point:
const minifyCSS = (css) => {
  return css.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, '') // remove comments
            .replace(/\s+/g, ' ') // collapse whitespace
            .replace(/ ?([{:};,]) ?/g, '$1'); // remove space around operators
}
Use code with caution.
JavaScript
4. Encoding & Hashing
Features:
Base64: Encode text to Base64 and decode from Base64.
URL: Encode and Decode URI components.
Hashing: Generate a SHA-256 hash from text input (useful for integrity checks).
Implementation:
Use the built-in Web APIs for robust and secure operations.
Generated javascript
// Base64 Encoding/Decoding
const handleBase64 = (action) => {
  try {
    setOutput(action === 'encode' ? btoa(input) : atob(input));
  } catch (error) {
    setOutput("Error: Invalid input for this operation.");
  }
};

// SHA-256 Hashing (async operation)
async function generateSha256(text) {
  const encoder = new TextEncoder();
  const data = encoder.encode(text);
  const hashBuffer = await crypto.subtle.digest('SHA-256', data);
  const hashArray = Array.from(new Uint8Array(hashBuffer));
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
Use code with caution.
JavaScript
5. Utility Generators
Features:
UUID Generator: Generate version 4 (random) and version 1 (timestamp-based) UUIDs.
Password Generator: Create strong, randomized passwords with configurable length and character types (lowercase, uppercase, numbers, symbols).
Implementation:
Use the Web Crypto API and the popular uuid library.
Generated javascript
// UUID Generation
import { v1 as uuidv1, v4 as uuidv4 } from 'uuid';

const generateUUID = (version) => {
  const newId = (version === 1) ? uuidv1() : uuidv4();
  setOutput(prev => prev + (prev ? '\n' : '') + newId); // Append new UUIDs
};

// Or for a simple v4 without a library:
const generateCryptoUUID = () => {
    setOutput(crypto.randomUUID());
}
Use code with caution.
JavaScript
UI/UX Considerations
Tool Switcher: A vertical sidebar with icons and labels for each tool category (Cleanup, Case, Format, etc.).
Layout: A responsive dual-pane layout. Input on the left, output on the right. On mobile, they stack vertically.
Real-time Updates: Output should update instantly as the user types or applies a transformation.
Copy & Clear: Prominent "Copy to Clipboard" buttons for the output and "Clear" buttons for both panes.
Theme & Styling:
Dark/Light Mode: A toggle switch in the header. Use CSS variables for easy theme switching.
Color Palette: A modern, purple-centric theme. (e.g., primary: #6D28D9, background-dark: #1F2937, text-dark: #E5E7EB).
Info Bar: A persistent footer bar displaying live Word Count, Character Count, and Line Count for the input text.
Deployment
Build: Create a production-ready build using a bundler like Vite or Create React App: npm run build.

Testing with Multiple LLMs

After setting up bolt.diy, I experimented with different LLMs to see how well each could generate the desired frontend structure based on the one-shot prompt. Below are my findings.

Test 1: Claude 3 Haiku

  • Model: anthropic/claude-3-haiku
  • Result: ❌ Unusable

Despite its speed and affordability, Claude 3 Haiku failed to generate meaningful output for this kind of frontend-heavy use case. The result was inconsistent and lacked structure.

bolt-diy-textforge-1st-run

Test 2: Claude 3.5 Sonnet

  • Model: anthropic/claude-3.5-sonnet
  • Result: ⚠️ Somewhat improved, but still unstable

This run delivered slightly better results with a more coherent layout, but many components were missing or incorrectly rendered.

bolt-diy-textforge-2nd-run

Test 3: Claude 3 Opus

  • Model: anthropic/claude-3-opus
  • Result: ⚠️ Best Claude response, but still lacking usability

This version yielded the most complete interface among the Claude family, yet the layout was cluttered and not very user-friendly.

bolt-diy-textforge-3rd-run bolt-diy-textforge-3rd-run-tool

Cost Breakdown via OpenRouter

Here’s the comparative cost across the three Anthropic Claude models based on their usage in this test setup:

bolt-diy-textforge-cost-breakdown

Test 4: DeepSeek Chat v3 0324 (Free Tier)

  • Model: deepseek/deepseek-chat-v3-0324:free
  • Result: ✅ Most successful and complete implementation

Despite being a free-tier model, DeepSeek V3 turned out to be the most reliable in generating a usable and well-structured UI for TextForge. It responded quickly, adhered closely to the prompt, and rendered a UI that was functional and clean.

bolt-diy-textforge-local-built

And the best part—it’s completely free to use.

Conclusion

Running bolt.diy locally with OpenRouter integration offers great flexibility in experimenting with different LLMs. Through this test, I was able to:

  • Rapidly prototype frontend components using natural language prompts

  • Understand the practical limitations of LLM-generated UIs

  • Compare real-world performance and cost trade-offs of multiple language models

Ultimately, TextForge is now working as a locally built and deployable app, backed by LLMs and fully customizable. The repo is publicly available here: 👉 https://github.com/seehiong/textforge

Whether you’re exploring local AI tooling, building developer utilities, or hacking together a prototype—bolt.diy is a powerful playground to bring ideas to life.