Inspiration
MochiDo was inspired by a simple problem: staying consistent with tasks and habits is difficult, especially when a goal feels too big. A normal to-do list can feel boring or easy to ignore, so we wanted to build something softer, more visual, and more encouraging.
The idea behind MochiDo is that big goals should become tiny tasks, and every tiny task should feel like progress. Instead of only checking items off a list, users grow a visual world as they complete daily actions.
What it does
MochiDo is a cozy productivity app where users can create a guest profile, write their own goal, choose a goal category, and receive tiny tasks connected to that goal.
Users can choose from guided categories:
Health → Wellness Island Career → Dream City Home → Cozy House Learning → Study Desk Custom Goal → My Mochi World
MochiDo also routes goals to a better category when it recognizes the user’s intent. For example, if a user types “running” or “eating,” the app treats it as a Health goal and creates a Wellness Island plan. If a goal does not clearly fit the four main categories, the user can use a Custom Goal with flexible tiny tasks.
Users can also edit task titles, so they still have control over their own plan. This makes the app feel more personal than a fixed to-do list.
The app supports:
Guest profile creation Multiple saved plans Previous plan history Custom goals Goal-aware task suggestions Editable task titles Daily task completion Progress tracking Streaks Upgrade stages Visual world growth
How we built it
I built MochiDo using Next.js, React, TypeScript, and Tailwind CSS. The app is deployed on Vercel, and the backend is implemented using Next.js API routes.
For the database layer, we used AWS DynamoDB as the primary backend database and connected to it using the AWS SDK for JavaScript. The frontend never talks directly to DynamoDB. Instead, the browser calls our API routes, and the API routes perform DynamoDB read and write operations.
MochiDo uses a single-table DynamoDB design. Instead of creating separate tables for users, plans, tasks, and progress, we store related data in one table using a partition key and sort key pattern.
PK = USER# SK = PLAN#
For example:
PK = USER#guest-1782754961 SK = PLAN#plan-1782755110
This design groups all plans for one guest user under the same partition. That means MochiDo can efficiently query a user’s saved plans without scanning the full table.
The main DynamoDB access pattern is:
Get all plans for one user: PK = USER# SK begins_with PLAN#
I use DynamoDB QueryCommand for reading user-specific plans and PutCommand for saving or updating plans. This lets the app support multiple saved plans per guest user while keeping the data model simple and scalable.
Each plan item stores both top-level metadata and the full plan object:
entityType = PLAN userId userName planId goalTitle goalType visualWorld repeatType createdAt updatedAt plan
Inside the plan object, we store:
tasks dailyHistory goalTitle goalType repeatType visualWorld
Task progress is stored in a dailyHistory map, where each date points to a list of completed task IDs:
dailyHistory: { "2026-06-29": [1, 2, 3] }
This means the user completed tasks 1, 2, and 3 on that date. The dashboard uses this persisted data to calculate daily progress, streaks, upgrade stages, total wins, and world level.
The main app flow is:
User creates a guest profile → Browser stores a lightweight guest user ID → User writes a goal → MochiDo routes the goal to a matching world or custom world → Plan is saved through POST /api/plans → API route writes the item to DynamoDB → Homepage calls GET /api/plans → API route queries DynamoDB for that user's plans → User opens a saved plan → Dashboard loads the selected plan from DynamoDB → User completes or edits tasks → Updated task state is saved back to DynamoDB → Visual world updates from persisted progress We also use Vercel environment variables to store AWS configuration securely:
AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_REGION DYNAMODB_TABLE_NAME
This keeps AWS credentials out of the source code and allows the deployed Vercel app to connect securely to DynamoDB.
The current MVP uses browser-based guest identity, but the DynamoDB model can scale to real authentication later. In a production version, the same pattern could use an authenticated user ID:
PK = USER# SK = PLAN#
Future entities could also be added with new sort key prefixes, such as:
SK = PROFILE SK = PLAN# SK = EVENT# SK = BADGE#
This makes the architecture flexible while preserving fast user-specific queries.
Challenges we ran into
One of the biggest challenges was turning a soft product idea into a working app. The original idea came from a personal problem: staying consistent with tasks is hard. But we did not want MochiDo to only solve one person’s problem or become just another habit tracker. We had to think more broadly about how different users might define progress, motivation, and consistency.
That pushed us to design MochiDo around flexible goals instead of fixed templates only. Users can write their own goal, choose a guided category, or use a custom goal. The app can route common goals like running, eating, or coding to a better experience, but still lets users edit task titles so the plan feels personal.
Another challenge was deciding how to structure the backend data. At first, it felt natural to think about separate tables for users, plans, tasks, and progress. But DynamoDB works best when the design starts from access patterns, not from traditional relational tables. We had to decide what the app needed to query most often.
The most important access patterns were:
Get all plans for one user Get one selected plan Save task progress for a plan Update edited task titles
Because of that, we chose a single-table DynamoDB design instead of creating many separate tables. Each user has a partition key like USER#, and each plan is stored under that user with a sort key like PLAN#. This keeps all of a user’s plans together and lets the app query previous plans efficiently.
Accomplishments that we're proud of
I am proud that MochiDo is a working full-stack app, not just a frontend prototype.
The app can:
Create a guest profile Save multiple plans for the same user Load previous plans from DynamoDB Save daily task completion history Reopen a plan and continue progress Let users edit task titles Route goals like running or eating to more relevant tasks Calculate streaks, progress, upgrade stages, and world level Deploy successfully on Vercel
We are also proud of the product experience. MochiDo makes productivity feel more gentle and rewarding by connecting small actions to a growing visual world.
What we learned
I learned how to build and deploy a full-stack app using Vercel and AWS DynamoDB. We also learned how important data modeling is when using DynamoDB, especially when designing around access patterns like “get all plans for this user” or “load a selected plan.”
We learned how to use environment variables safely, how to connect a Vercel-hosted app to AWS, and how to persist real app state in the cloud.
Most importantly, I learned that a technical project does not have to feel cold or complicated. MochiDo combines cloud infrastructure with a warm user experience to make consistency feel more approachable.
What's next for MochiDo
Next, MochiDo could add real authentication, stronger data modeling, richer visual worlds, reminders, and deeper long-term progress analytics.
The current guest user system could be replaced with authenticated user IDs while keeping the same DynamoDB access pattern:
PK = USER# SK = PLAN#
A future version could also expand the DynamoDB model beyond plans. For example, MochiDo could store separate item types for profiles, progress events, badges, streak history, and world upgrades using new sort key patterns:
SK = PROFILE SK = PLAN# SK = EVENT# SK = BADGE# SK = WORLD#
This would make the data model more flexible and allow the app to support richer analytics, such as weekly consistency, most completed task types, long-term goal progress, and how a user’s habits change over time.
MochiDo could also add AI, but in a careful way. I do not want AI to take over the user’s goals or tell them what they should do. The user should still own their goal, their tasks, and their direction. Instead, AI could be used to provide gentle motivational phrases, encouragement, reflection prompts, or celebration messages after small wins.
For example, after completing a task, AI could generate a short supportive message like:
Small steps still count. You showed up today.
This keeps the app human-centered. AI would support the user emotionally without replacing their agency or deciding their goals for them.
Future versions could also let users customize their visual worlds more deeply, add mobile widgets, and personalize the tone of motivational messages so MochiDo feels like a gentle companion for building consistency over time.
Built With
- aws-dynamodb
- aws-sdk-for-javascript
- github
- next.js
- next.js-api-routes
- react
- tailwind-css
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.