MoreRSS

site iconThe Practical DeveloperModify

A constructive and inclusive social network for software developers.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of The Practical Developer

How I Finally Forced LLMs to Return Perfect JSON (2025 Edition) — No Hacks, No Regex, Just Clean Output

2025-12-04 02:39:23

If you’ve ever worked with LLMs in real applications — especially with LangChain + TypeScript — you probably know the frustration:

  • Broken JSON
  • Extra text wrapped around JSON
  • Random “creative” outputs
  • Parsers blowing up in production

I’ve personally gone through it all.
As someone who builds AI apps, RAG chatbots, and SaaS platforms using Next.js, LangChain, Supabase Vector Store, Pusher, and more — I tried every prompt trick to force LLMs to follow a strict JSON structure.

I told the model:

“Return valid JSON only.”

I added strict instructions.
I wrapped the prompt with do’s/don’ts.
I used regex cleanups.
I even attempted post-processing pipelines.

Nothing worked reliably.
Because the truth is simple:

Prompts alone can never guarantee valid JSON.

LLMs aren’t designed to obey formatting rules consistently.
But in 2025, the solution finally became production-ready:

The Fix: LangChain .withStructuredOutput() + Zod

This combination forces the model to return:

  • 100% valid JSON
  • Fully typed data
  • Schema-safe responses
  • No extra text
  • No formatting issues

And the best part?
It works with:

  • Google Gemini
  • OpenAI (GPT-4o, o-mini)
  • Groq (Llama 3.1)
  • Anthropic Claude

What You’ll Learn in My Guide

👉 How .withStructuredOutput() works internally
👉 Step-by-step Next.js 16 + TypeScript implementation
👉 API route with proper error handling
👉 Zod schema for strict output validation
👉 Clean UI example using shadcn/ui
👉 Why this method is faster, cheaper & more reliable than old hacks

This guide is for anyone building AI-powered apps — chatbots, agents, extractors, RAG systems — where structure matters.

Read the full guide:
🔗 How to Force Perfect JSON Responses in LangChain with TypeScript (2025 Edition)

About the Author

Arfatur Rahman — Full Stack Developer from Chittagong, Bangladesh.
I build AI-powered applications using Next.js, TypeScript, LangChain, Supabase, Pusher, and Google Gemini.
I specialize in RAG systems, real-time AI chat widgets, and full SaaS platforms.

Follow me for more guides on AI, LangChain, and modern web development.

Boost Your Learning with Hidden AI Tools for Students

2025-12-04 02:39:09

Students and lifelong learners — struggling to keep up with lectures, assignments, or research? There’s a set of AI tools for students that can make your workflow smarter and faster.

Tools like Mem.ai help organize notes, Perplexity.ai provides concise research answers, Recall.ai summarizes video lectures, Explainpaper.com simplifies dense papers, and Notion AI helps you plan and draft work efficiently.

These tools are free to start, integrate easily into your daily workflow, and save hours of manual effort. Whether you’re coding projects, preparing research, or just trying to stay organized, adding AI to your study routine is a game-changer.

Check out our full guide to discover how these hidden AI tools can transform the way you learn.

Detail Review: https://napnox.com/ai-tools/secret-ai-tools-for-students/

Embedding Serverless Dashboards in React

2025-12-04 02:35:50

I know how devs building web apps often need to embed dashboards and are looking for ones that are easy to integrate and include interactivity. Something else to consider is low-cost scalability, meaning low resource costs. Serverless apps are the answer. One of them is called StyleBI, and you can embed interactive dashboards directly into your React app, enforce row-level security per user, and scale elastically without managing servers or paying for instances when no one is using the dashboards. It connects seamlessly to common data sources like AWS, Postgres, or Snowflake, giving your users real-time insights while keeping operational overhead low. Here’s a simple example of embedding:

`import React from "react";

const Dashboard = () => {
return (
src="https://your-stylebi-instance.com/embed/dashboard-id?userToken=YOUR_USER_TOKEN"
width="100%"
height="600"
style={{ border: "none" }}
title="User Analytics Dashboard"
/>
);
};

export default Dashboard;
`
The idea is that with serverless BI you can focus on building features and delivering insights rather than managing infrastructure or wasting money. There is an open source version on GitHub.

Day 10: Mastering Terraform Expressions - Conditional Logic, Iteration, and Collection

2025-12-04 02:35:39

This is Day 10, and we are diving deep into Terraform Expressions. Expressions are a fundamental concept, providing powerful, concise syntax that helps avoid rewriting code repeatedly. While similar in function to what we will later cover in Terraform functions, expressions offer immediate utility in making your configurations dynamic and reusable.
We focus today on three key expression types: Conditional, Dynamic Block, and Splat.

                ┌───────────────────────────────────────────┐
                │   Terraform Expressions                   │
                │   Simplify Configurations & Reduce Repetition │
                └───────────────────────────────────────────┘
                                │
   ┌────────────────────────────┼────────────────────────────┐
   │                            │                            │
   ▼                            ▼                            ▼
┌─────────────────┐      ┌────────────────────┐       ┌────────────────────┐
│ Conditional      │      │ Dynamic Blocks     │       │ Splat Expressions  │
│ Expressions      │      │ (nested iteration) │       │ (retrieve multiple │
│ (true/false logic)│     │                    │       │ attributes)        │
└─────────────────┘      └────────────────────┘       └────────────────────┘
   │                        │                            │
   ▼                        ▼                            ▼
┌─────────────────┐   ┌────────────────────┐       ┌────────────────────┐
│ Syntax:          │   │ Syntax:            │       │ Syntax:            │
│ condition ?      │   │ dynamic "block" {  │       │ resource.*.attr    │
│ true : false     │   │   for_each = list  │       │                    │
└─────────────────┘   │   content {...}     │       └────────────────────┘
                      └────────────────────┘
   │                        │                            │
   ▼                        ▼                            ▼
┌─────────────────┐   ┌────────────────────┐       ┌────────────────────┐
│ Example:         │   │ Example:           │       │ Example:           │
│ EC2 instance     │   │ Security Group     │       │ Collect EC2 IDs    │
│ type selection   │   │ ingress rules      │       │ into a list        │
└─────────────────┘   └────────────────────┘       └────────────────────┘


1. Conditional Expressions: True or False Logic

A conditional expression is a simple, one-line piece of syntax that functions like an if/else statement found in most programming languages. It evaluates a condition and returns one of two specified values (the true value or the false value).

The Structure:
The conditional expression is always written as: condition ? true_value : false_value. The colon (:) separates the true value from the false value.

Code Example (Environment Selection):

This is most commonly used to set resource attributes based on environment variables. For instance, we can specify that if the environment is dev, a smaller instance type is used; otherwise, a larger one is selected.

variable "environment" {
  type    = string
  default = "staging" // Will select the false value
}

resource "aws_instance" "example" {
  // If var.environment == "dev" is TRUE, use T2 micro.
  // If FALSE (e.g., staging/prod), use T3 micro.
  instance_type = var.environment == "dev" ? "t2.micro" : "t3.micro" [4, 6]

  // ... other configuration ...
}

As demonstrated in the demo, changing var.environment from dev to anything else (like staging or prod) immediately switches the instance type in the execution plan.

2. Dynamic Blocks: Nested Iteration

Dynamic blocks are essential when you need to write a nested block with multiple values within a resource definition. They help avoid manual repetition of configuration. This is frequently used for managing repeated elements, such as ingress or egress rules within an AWS Security Group.

The Structure and Iteration:

A dynamic block starts with the dynamic keyword, followed by a name (e.g., ingress). Inside, it uses a for_each argument to iterate over a collection (often a complex list of objects, like var.ingress_rules). The resource definitions must be placed within a content block.
When iterating, you access the attributes of the current element using the dynamic block name (e.g., ingress) and the special iterator object (value): ingress.value.from_port.

Code Example (Security Group Rules):

If we define two ingress rules (one for HTTP on port 80, one for HTTPS on port 443) in a list of objects variable, the dynamic block iterates through the list:

// Example Variable (List of Objects containing port, protocol, etc.) [8, 14]

resource "aws_security_group" "ingress_rule" {
  // ... other attributes ...

  dynamic "ingress" {
    for_each = var.ingress_rules // Iterates through the list of rules [11]

    content {
      from_port   = ingress.value.from_port [12] 
      to_port     = ingress.value.to_port [12]
      protocol    = ingress.value.protocol [12]
      cidr_blocks = ingress.value.cidr_blocks [12]
    }
  }
}
// This single block generates multiple ingress rules in the plan [15].

3. Splat Expressions: Retrieving Multiple Attributes

The splat expression is another powerful one-liner used to retrieve a list of attributes from a set of resources. This is most useful when dealing with resources that were created using the count meta-argument, meaning they exist as a collection.
The splat expression uses the star operator ().
The Structure:
The expression is written as: resource_list.
.attribute.

Code Example (Collecting Instance IDs):

If we use count = 2 to create two EC2 instances (aws_instance.example), the splat expression retrieves the ID attribute for both instances and collects them into a list:

locals {
  // Collects the 'id' attribute from all instances named 'example'
  all_instance_ids = aws_instance.example.*.id [16-18]
}

output "instances" {
  value = local.all_instance_ids [19]
  // Value will be known after apply [19].
}
This efficiently creates a list containing [id_of_instance_0, id_of_instance_1].

Mastering these expressions allows you to write truly dynamic and concise Infrastructure as Code. Make sure you complete the hands-on practice in the Day 10 GitHub repository to solidify your learning from @piyushsachdeva

No Vibe No Code: Bootstrapping Ideas

2025-12-04 02:34:20

1. The Core Problem: Too Many Ideas, Not Enough Finished Things

I always have loads of ideas for projects. Often I start them, and most of the time I don't even finish them. My problem isn’t creativity. The problem is that most of those ideas never make it past the “oh, that would be cool” stage.

So I end up with this growing backlog of “things I could build someday” and no clear way to:

  • store them
  • compare them
  • or decide which one actually deserves my time

I saw an opportunity in this Kiroween Hackathon to build an app where I could:

  • dump all my ideas
  • validate them against the hackathon (or any) criteria
  • and then actually move them towards something shippable

And so No Vibe No Code was created.

2. What is No Vibe No Code?

The core concept is from idea to vibecoding (or spec-coding in Kiro's case)

At a high level, No Vibe No Code is A place to bootstrap your ideas and get them into a Kiro-ready, development-ready shape as quickly as possible.

Here is an example of the user flow:

Step 1: Get an idea (or generate one)

  • Write your own idea – maybe something that’s been sitting in your notes app for months

Or

  • Use Dr. Frankenstein, this is basically a chaotic idea generator (inspired by the Kiroween category)

I personally love Dr. Frankenstein feature on No Vibe No Code because it randomly picks a few popular tech companies or a few AWS services -> Smashes them together -> And creates some weird hybrid idea that actually fits nicely for hackathon-style creativity.

Dr Frankenstein selecting Tech Companies to mix up

Dr Frankenstein selecting AWS Services to mix up

Step 2: Validate your idea

Ok, so I have 100s of ideas, but how do I know if they are good ideas? How do I know if they are feasible? Are they even good ideas for this hackathon?

For that, we've added a 'Kiroween Analyser'. This feature will generate a report against the hackathon criteria and score it accordingly.

Our own score in the Kiroween Analyser

This validator opens a possibility to add multiple validators that can serve to analyse ideas against specific criteria like hackathons, games, small side-projects, the possibilities are endless. In this case, we were focused on Kiroween.

Kiroween Category match

Step 3: Generate some core documents

Once you have an idea (manual or Frankenstein’ed), No Vibe No Code helps you generate the core docs you need to support your building:

  • A PRD – to clarify the problem and the user
  • A technical design doc - to describe how the solution will work at a feature level
  • An architecture design - to map the high-level components, services, and boundaries (more tech-oriented)
  • A roadmap for an MVP – to define the smallest version worth shipping and how to get there

Documents generation flow

The goal is: your idea stops being just a sentence and starts becoming a structured concept.

Step 4: Power up Kiro

Once those docs exist, you can export to kiro:

No Vibe No Code will then:

  • Generate steering rules for Kiro
  • Generate spec templates aligned with your roadmap

Export to Kiro

So instead of opening Kiro with a blank chat and writing “Help me build X,” you:

  • Walk in with a defined idea
  • Have a PRD, design, architecture, and MVP roadmap
  • Already have steering rules and spec scaffolding ready to go

From there, you can just start kicking off specs and building.

That’s the main idea of No Vibe No Code:

from raw idea → structured docs → Kiro-ready boilerplate, with as little friction as possible.

Demo

3. Building Before Kiro

Because of my background as a platform / DevOps engineer, I naturally thought in terms of structure: roadmaps, milestones, and tasks.

So my workflow looked roughly like this:

Create a PRD or Readme with context for the project -> Create a roadmap with milestones to achieve and divided by tasks -> Ask the AI to implement each task based on those documents.

At the time, I didn’t even realise there was a name for what I was doing!!

So when I eventually discovered Kiro and saw its spec-driven development focus, I had this moment of:

“Hold on your horses… they’re doing exactly what I’ve been trying to do, just… better.”

That’s when I decided to go all in on Kiro.

4. My Journey with Kiro

When I first set up Kiro for this project, I went with the default, raw setup:

  • No custom steering rules
  • No MCPs
  • No hooks

Obviously, this wasn't ideal as I was missing a lot of features.

Discovering Kiro’s Best Practices

In my first week, I joined the Kiro Discord and started reading through posts and getting to know best practices and how other people were building with Kiro.

Around that time, Kiro also released the MCP Server directory, which made it much easier to install MCPs.

I also discovered that Kiro could auto-generate some basic steering files for things like: tech, structure and product.

Taking it to the next Level

From there, my Kiro setup evolved gradually:

  • Started adding steering rules and adapting them to my setup.
  • Wired in some useful MCPs (context7, github, supabase).
  • Using rules for inclusion on steering and triggers on hooks

Over days and weeks, this went from:

“Just raw Kiro, let’s see what happens.”

to:

“I have a small ecosystem here that actually understands how I like to work.”

Models - From autopilot to Opus 4.5

When I started this project, I kicked things off using Kiro Auto model. I wasn't sure if I was going to burn all my credits with the other models, and I didn't know the actual difference between those models. Default seems like a good plan.

For a big chunk of the journey, Auto was genuinely fine. Sometimes it produced bugs or weird decisions but nothing too critical.

Later on, when I saw I still had credits left, I decided to experiment a bit.

Sonnet 4.5

I tried Sonnet 4.5 for a few specs. Overall, it felt the same as Auto model bit more expensive. I still had to babysit some results and debug like crazy.

But then... There was an announcement!

Opus 4.5

Opus 4.5 landed, at x2.2 cost and with 500 credits left for the month, I decided to go all in with Opus for the last few specs.

That’s where I actually felt the difference. The code quality was noticeably higher, and there were fewer bugs (still some, but manageable).

Yes, it’s more expensive, but for the final specs, where I really cared about quality and didn’t want to waste time chasing edge cases, it felt absolutely worth it (I ended the month with 50 credits left)

Adding Property-Based Testing to the mix

Kiro announced Property-based testing halfway through Kiroween. It was such a good concept that I couldn't resist spending a spec on this.

Asking on discord about Property-based testing

After implementing it, I felt more comfortable trusting AI-generated code. It aligned well with the whole “let’s automate the boring but important parts” mindset. It creates a pretty solid safety net.

7. What I’d Do Differently (And how No Vibe No Code can help)

Let's recap on my journey:

  • Started with a raw Kiro setup (no steering, no MCPs, no hooks).
  • Added things gradually, as I discovered them.
  • Let my IDE configuration drift and change over time.
  • Tweaked the ecosystem spec by spec.

That worked, but it could have been a smoother experience. What I’d prefer instead is a solid boilerplate from day one: sensible project structure, steering rules setup, and documentation to get ready to spec.

And that’s exactly the point of No Vibe No Code. I want a place where I can show up with an idea, press a few buttons, and end up with:

  • project docs generated.
  • clear path from idea → MVP.
  • boilerplate Kiro ready.

If there’s no vibe with the idea and documents, there’s no code

Share your Work and Ideas

You can try it out now!! Go to No Vibe No Code

You can spin up your own No Vibe No Code too!! Open Source GitHub repo: (https://github.com/llamojha/no-vibe-no-code-kiroween)

If you end up playing with this No Vibe No Code workflow, I’d genuinely love to see what you come up with.

In particular:

  • What Dr. Frankenstein ideas did you generate?
  • Which ones actually made it past the “haha that’s funny” stage and into a real PRD / design / roadmap?
  • How was your experience going from raw idea → Kiro → working thing?
  • If you think I should rebrand to No Vibe No Spec

Let’s get building!!