I recently developed Rap Dojo, a web service that uses AI to generate rap lyrics. In this article, I’ll share how the project came about, how I built it, and what I learned from launching and running it.
My original motivation was simple: I wanted to build a working product using an LLM API.
Around that time, Google and Zenn were hosting a Gemini-related hackathon, and I thought, “If I’m going to build something, why not make something interesting with Gemini?”
That idea led me to start developing Rap Dojo.
The concept was an AI rap generator that would make it easy for anyone to create a rap.
Of course, you can already ask a conversational AI such as ChatGPT or Gemini to “write me a rap,” and it will generate one for you.
But when you actually use a chat interface, that freedom can sometimes be overwhelming. People may wonder:
With Rap Dojo, I wanted to create an experience simple enough that users could generate a rap by entering just a few words, without having to think about complicated prompts.
For example, you might enter your name, something you like, or something that happened recently, and the AI will turn those ideas into a rap.
I thought that if the experience were simple enough, even people who rarely use generative AI might feel comfortable playing around with it. It could make AI-generated content feel a little more accessible and integrated into everyday life.
That became the starting point for Rap Dojo.
I intentionally kept Rap Dojo’s architecture as simple as possible.
At a high level, it consists of:
The frontend calls the backend API through JavaScript. The backend then uses Gemini to generate a rap based on the user’s input and returns the result to the frontend.
For the frontend, I decided not to use a framework such as React or a CMS. It is built primarily with HTML and CSS, with some JavaScript.
One reason I chose this approach is the rapid progress of AI coding tools.
Today, tools such as Claude Code and Antigravity make it possible to build and modify websites efficiently using natural-language instructions.
For a relatively small web service like this, I therefore felt that introducing a CMS or a large JavaScript framework was unnecessary.
I’m also comfortable working directly with HTML and CSS, so editing the code myself does not create much overhead.
Keeping the architecture simple provides several benefits:
For small websites and indie projects, I’ve come to believe that avoiding unnecessary technical complexity can be just as important as choosing the right technology.
I use Google Cloud Run for the backend.
Rap Dojo does not receive a large volume of traffic continuously, so I did not want to run a server 24/7.
Instead, I chose Cloud Run because its serverless model allows the backend to run only when needed.
Conceptually, the flow looks like this:
User input
↓
Frontend (JavaScript)
↓
Cloud Run API
↓
Python / LangChain
↓
Gemini API
↓
Rap generation
↓
Result returned to frontend
Once the user input is received, the backend performs the generation process and returns the output to the frontend through the API.
One of the biggest benefits of this architecture is its low operating cost.
Gemini API usage naturally incurs costs depending on usage, but at Rap Dojo’s current traffic level, the Google Cloud infrastructure costs are extremely low.
The exact amount varies by month, but infrastructure costs generally stay below a few hundred yen per month.
In the past, launching a web service with a backend meant thinking about servers, hosting, maintenance, and other infrastructure concerns.
Today, by combining a serverless environment such as Cloud Run with a generative AI API, even an individual developer can launch a web application that accepts user input and processes it dynamically at very low cost.
Building Rap Dojo reminded me just how much the barrier to launching this kind of product has fallen.
I use Gemini as the LLM behind Rap Dojo.
The biggest reason is its strong balance between cost and quality.
In particular, Gemini’s Flash models offer relatively low API costs while still providing more than enough quality for text-generation use cases like this one.
Every time a user generates a rap, the application makes an LLM API call. As usage grows, those costs accumulate.
That means indie developers need to think not only about model performance, but also about the cost of each generation.
From that perspective, I’ve found the Gemini Flash family very practical for personal projects.
Another reason I often use Gemini is that Google Cloud credits are relatively accessible through developer programs and events.
Google regularly organizes developer events and hackathons, and participation sometimes comes with Google Cloud credits.
Although these credits typically expire, some events provide credits worth around ¥10,000–¥20,000, which can be very useful for indie development.
Making good use of those credits is another reason the Gemini API has become my main choice for personal projects involving LLMs.
Rap Dojo currently uses different models depending on the task:
Rather than using the most powerful model for every task, I use lighter models where appropriate. This helps keep costs down while maintaining the generation quality I need.
For indie development, I’ve learned that model selection should not simply be about choosing the “best-performing” model. It is equally important to consider how cheaply you can operate while still meeting the required quality level.
In Rap Dojo, the rap-generation process is implemented as a two-stage pipeline.
At a high level, it works like this:
User input
↓
1. Generate the rap
↓
2. Format the output
↓
Display to user
The main reason I use LangChain is that I wanted a convenient way to connect multiple LLM operations sequentially.
The first step is to generate the rap itself.
At this stage, rather than controlling the output format too strictly, I give the LLM more freedom and prioritize creativity and entertainment value.
With rap lyrics, overly strict formatting requirements can make the output more consistent, but they can also make the writing feel repetitive or less expressive.
So in the first stage, I prioritize the quality of the content itself.
The generated rap is then passed to a second process that adjusts it into a format that works well on the website.
For example, this stage can:
This step does not require particularly advanced creative ability, so I can use a lighter and cheaper model such as Gemini 3.5 Flash-Lite.
In other words:
Each model has a different role.
Initially, I considered handling everything within a single prompt:
“Write a rap and output it in this exact format.”
But after experimenting with the application, I found that separating content generation from output formatting made the system easier to manage.
Instead of asking a single model to do everything, I split the process into:
Generate
↓
Review / format
This also allows me to choose a model that is appropriate for each task.
Even though Rap Dojo has a relatively simple architecture, I still needed a convenient way to manage multiple LLM operations as a pipeline. That is the main reason I decided to use LangChain.
I use Google Cloud Run to deploy the backend.
There are several ways to deploy a Python-based web application, so during the early stages of development I considered a number of options, including:
For this particular use case, however, I found Cloud Run to be the easiest option while also keeping costs low.
With Rap Dojo, I did not want to publish only an AI demo. I wanted to integrate the rap-generation feature into a proper website running on the custom domain rapdojo.com
.
Services such as Streamlit Cloud and Hugging Face are extremely useful for publishing AI application prototypes.
For the architecture I had in mind, however, it was easier to have an existing custom-domain website call a Python backend through an API.
With Cloud Run, the architecture can be cleanly separated like this:
rapdojo.com
HTML / CSS / JavaScript
↓
Cloud Run API
↓
Python
↓
Gemini API
The website itself remains a conventional HTML website, while Cloud Run handles only the parts that require AI processing.
Another reason Cloud Run works particularly well for Rap Dojo is that a small indie service like this does not need a backend running continuously.
Python only needs to execute when someone generates a rap.
For that reason, a serverless service such as Cloud Run was a better fit than maintaining an always-on server.
At relatively low traffic levels, infrastructure costs can remain very low as well.
I think Cloud Run is a practical option when you want to add Python or generative AI functionality to specific parts of an otherwise conventional website.
I used to associate AI apps with specialized application environments, but in practice, combining a standard HTML-based website with Cloud Run was enough to launch a fully functional service.
One thing I noticed after operating Rap Dojo in production is the instability that comes with relying on an external LLM API.
With a conventional website, as long as your own servers and code are functioning correctly, you can generally continue providing the service.
A generative AI application introduces another dependency:
Rap Dojo
↓
LLM API
↓
External AI service
As a result, even when there is nothing wrong with your own code, the application may temporarily become unavailable because of issues on the LLM provider’s side.
During the early development of Rap Dojo, I used a GPT API.
At one point, an API specification change caused a process that had previously been working to suddenly stop.
I had not changed my own code, but a change to the external API still affected the service.
That experience made me much more aware of this risk.
I had similar experiences after switching to Gemini.
With one of the Gemini Flash models I was using at the time, high load on the model side occasionally resulted in API errors, temporarily preventing users from generating rap lyrics.
The service is more stable now, but once you operate a real product, you quickly realize that you cannot assume an LLM API will succeed 100% of the time.
The main lesson from this experience is that when building a generative AI service, implementing only the success path is not enough.
You also need to consider scenarios such as:
For a production service, it is important to think about what happens when the LLM fails, including error messages, retries, and potentially falling back to another model.
In traditional web development, I mainly thought about my own code and infrastructure.
AI web applications add another dependency: the external LLM service.
Operating Rap Dojo taught me that designing around this dependency is an important part of building AI products.
After launching Rap Dojo, I learned several things beyond the technical side of development.
One of the most interesting lessons was that even a small web service on a brand-new domain can attract meaningful traffic if it combines a niche user need with effective SEO.
For Rap Dojo, I registered the domain rapdojo.com
and built the site with SEO in mind from the beginning.
SEO is also part of my professional background, so I researched search demand and optimized the site and its content accordingly.
As a result, the site began ranking for relevant Japanese keywords such as “ラップ AI” (“rap AI”) and “ラップ 作って” (“make me a rap”).
Today, around 3,000 people visit the site each month.
Of course, this is not a large-scale service. But considering that I am not running any advertising and started from a completely new domain, I think it is an encouraging result for an indie web application.
This experience made me think that the following combination can work particularly well for indie projects:
Niche search demand
+
A genuinely useful tool
+
SEO
There was, however, another important lesson.
Getting users to visit a product and turning that product into a viable source of revenue are two completely different challenges.
Rap Dojo is mainly something people use casually for fun, and I do not think it is the kind of service most users would pay for.
For that reason, it remains essentially free to use.
However, even a free service has operating costs.
Gemini API, Google Cloud, and other services all cost a small amount of money each month.
That creates a simple situation:
“There is no revenue, but the product still costs a little money every month.”
At the same time, the site has gained search rankings and people are actively using it, so shutting it down feels like a waste.
As a result, Rap Dojo has become a product that I continue to maintain while paying a small amount each month to keep it running.
For one project like Rap Dojo, this is not a major issue.
But if I were to create five or ten similar personal projects, each one would come with API fees, cloud costs, domain fees, and ongoing maintenance work.
That has made me realize that for my next web product, I should think not only about building and launching it, but also about how I plan to maintain it afterward.
For example:
Defining criteria like these in advance may be useful.
With indie development, building and launching something is fun in itself, so it is easy to keep creating new products without thinking too much about what happens afterward.
However, if you want to manage several products over the long term, deciding what to keep and what to shut down may be just as important as deciding what to build.
That said, I currently have no plans to shut down Rap Dojo.
I do not plan to make major feature additions or actively develop it on an ongoing basis, but I still use it from time to time to create rap lyrics for fun.
Rather than trying to turn Rap Dojo into a large business, I plan to maintain it as a small AI product that I built and still use myself.
From a monetization perspective, it has not been a successful product.
But in terms of what I learned, the project has been extremely valuable:
Overall, it has been a very rewarding project.
I’d like to finish with a short introduction about myself.
As a hobby, I build AI-powered products and indie projects like Rap Dojo.
Professionally, I primarily work in SEO, and more recently I have also been conducting research and analysis related to GEO and AI Search.
My main areas of interest include:
When it comes to indie development, I enjoy more than simply writing code.
I like coming up with an idea, turning it into a real product, launching it, attracting users through SEO, and then operating and improving it over time.
If you read this article and thought:
I’d be very happy to connect.
You can find more information about the projects and research I’m working on here:
Heysho