How to Build an Internal Tool for Your Team Without Code
- What you need
- A Creatr account on a plan that supports multi-role apps
- Token cost
- Moderate
- Time
- About 90 minutes

That spreadsheet your ops team lives in - the one with color-coded rows, a tab called "DO NOT TOUCH," and a Slack message every Monday asking who updated column G - is an app waiting to happen. Building internal tooling is not a lower bar than building for customers. In some ways it is higher: your teammates will notice every rough edge immediately, and you cannot lose their trust the way you might with a free-tier user. This tutorial walks you through building a real internal tool on Creatr by describing what you need in plain English, no code required.
Before you start
Map the workflow on paper before you open a browser. Thirty minutes here saves days of revision later. Answer four questions:
- What is the single job this tool does? (Approve vendor invoices. Track support escalations. Manage content calendar.)
- Who are the people using it, and what is each person's job inside the tool?
- What information moves through the workflow - what goes in, what gets decided, what comes out?
- What does "done" look like for one unit of work?
If you cannot answer all four, the tool is not ready to build yet. Go talk to the people who will use it and watch them work for an hour. The spreadsheet they hand you will answer most of the questions.
One more thing: internal access control is almost always more complex than what you would build for external users. A customer-facing app often has two roles - logged in or not. An internal tool might have six: viewer, editor, approver, manager, finance, and admin. Each role sees different data and can take different actions. Plan that complexity upfront; retrofitting it is painful.
Step 1 - Describe the workflow the tool replaces
Start by telling Creatr what the tool does in one clear sentence, then describe the current manual process.
"I need an internal tool for approving vendor invoices. Right now my team receives invoices by email, logs them in a spreadsheet, and sends a Slack message to the finance lead to approve or reject. Finance leads annotate the spreadsheet with their decision and a reason. The tool should replace that whole cycle."
Be specific about the current pain. If approvals sometimes take four days because someone forgot to check Slack, say that. Creatr uses that context to wire in the right defaults - notifications, status fields, assignment logic - at build time rather than as afterthoughts.
Step 2 - Model the data
The columns in your spreadsheet are fields in a database table. Name them explicitly in your prompt. Do not assume Creatr will guess them from context.
"The invoice record should store: vendor name, invoice number, invoice date, amount, currency, payment due date, a file attachment for the PDF, current status (Pending / Approved / Rejected / Paid), the name of the person who submitted it, the name of the approver, an approval or rejection reason, and the date the decision was made."
If your tool manages more than one type of record - say, invoices and vendor profiles - describe each one separately and say how they relate.
"Each invoice belongs to one vendor. The vendor record stores the vendor name, contact email, payment terms, and whether the vendor is active. A vendor can have many invoices."
Good data modeling at this stage means you will not need to ask Creatr to add fields later and re-test every form that touches them.
Step 3 - Roles and permissions
This is where most internal tools get underspecified. List every role and, for each role, describe what they can see and what they can do.
"There are three roles:
Submitter - can create new invoices and upload the PDF, can see only their own submitted invoices, cannot approve or reject anything.
Finance Lead - can see all invoices assigned to them, can approve or reject with a required reason, cannot edit the invoice amount or vendor name after submission.
Admin - can see all invoices, can reassign invoices to a different finance lead, can mark an approved invoice as Paid, can deactivate vendors."
Write this out even if it feels obvious. The difference between "Finance Lead can see all invoices" and "Finance Lead can see only invoices assigned to them" will produce two different apps, and you want the right one on the first build.
If certain fields should be visible to some roles but not editable, say so explicitly. Finance should probably see the submitted amount but not be able to change it after the fact - that is an audit integrity requirement, not just a nice-to-have.
Step 4 - Forms and actions for the daily work
Every role has a set of things they do repeatedly. Describe those workflows as actions with inputs and outcomes.
"When a Submitter creates a new invoice, the form should require: vendor (selected from the active vendor list), invoice number, invoice date, amount, currency, payment due date, and a PDF upload. On submission, the invoice status should be set to Pending and it should be assigned to the Finance Lead for that vendor."
"When a Finance Lead reviews an invoice, they should see the full record and the attached PDF in the same view. They should be able to click Approve or Reject. Rejection requires a typed reason of at least 20 characters. After either action, the submitter should receive a notification."
"When an Admin marks an invoice as Paid, they should be prompted to enter the payment date and payment reference number. The status should update to Paid and the record should lock - no further edits allowed."
The more concrete you are about what a button does and what happens next, the closer the first build will be to what you actually want. Vague verbs like "manage" or "handle" produce vague apps.
Step 5 - An audit log
Who changed what, and when - this is non-negotiable for anything touching money, access, or compliance. Tell Creatr you want it.
"Every change to an invoice record should be logged: the field that changed, the old value, the new value, the user who made the change, and the timestamp. This log should be visible to Admins on the invoice detail page. It should not be editable by anyone."
An audit log is not just a compliance artifact. It is the answer to every "why is this marked rejected?" conversation your team will have. Build it from the start.
If your tool integrates with Gmail for email notifications, the log should also record when notification emails were sent and to whom. That way, "I never got the email" has a factual answer.
Step 6 - A dashboard or overview
Every person who logs in needs a clear answer to "what do I need to do right now?" before they start hunting through lists.
"The Finance Lead dashboard should show: a count of invoices pending their review, the three oldest pending invoices by submission date, and a summary of total invoice value approved this month. The Submitter dashboard should show the status of their last five submitted invoices and a button to submit a new one. The Admin dashboard should show total pending, approved, rejected, and paid invoices for the current month, and a list of vendors with overdue invoices."
Different roles seeing different dashboards is the right default. A Submitter does not need to see the finance summary. An Admin does not need the submitter's quick-submit button in their face.
Step 7 - Notifications
Notifications are where internal tools either build trust or destroy it. An approval that silently completes - with no message to the submitter - feels broken. An approval that triggers five emails feels like spam. Be precise.
"When an invoice is submitted, send a notification to the assigned Finance Lead via Slack with the vendor name, amount, and a direct link to the record. Do not send email for this - the team uses Slack.
When an invoice is approved or rejected, send an email notification to the submitter with the decision, the reason if rejected, and a link to the record. Also post a Slack message to the #finance channel summarizing the decision.
When an invoice has been pending for more than 48 hours with no action, send a reminder to the assigned Finance Lead via Slack."
Time-based reminders (the 48-hour escalation above) are one of the most valuable things an internal tool does over a spreadsheet. The spreadsheet never reminds anyone of anything. Describe reminders the same way you describe any other action: trigger, recipient, message, channel.
Step 8 - Test with the people who will use it
Creatr ships a production URL. Before you tell anyone it is ready, sit down with one person from each role and watch them try to do their actual job in the tool.
Do not narrate. Do not explain. Just give them a task - "submit an invoice for Acme Corp, $4,200, due next Friday" - and watch. The places where they hesitate or ask questions are the places the tool is unclear.
Common things that surface at this stage:
- A required field that should be optional (or vice versa).
- A status that makes sense to you but confuses the person doing the work.
- A form that forces the user to look up information they do not have at their desk.
- A notification that fires for every minor edit, making it noise instead of signal.
Write down what you observe, not what they say. People will often say "it's fine" while clearly being confused. What their hands do is more honest.
Step 9 - Ship and iterate
Once the people doing the work can complete their core tasks without asking you questions, the tool is ready to replace the spreadsheet. Do not wait for it to be perfect. Perfect is the enemy of deployed.
On day one, keep the old spreadsheet around as a fallback. Do not delete it. Tell your team they can use it if something feels wrong, but ask them to flag the issue immediately so you can fix it. By the end of the first week you will know whether the tool handles real edge cases or only the ones you planned for.
The second round of improvements almost always comes from two sources: the audit log showing you that certain fields get edited constantly (which means the form should have been different), and Slack messages asking "how do I..." (which means a workflow that exists in someone's head but not in the tool).
Feed both back into Creatr as plain-English change requests. Describe what is happening now and what you want to happen instead. The same discipline that produced the first build will produce clean iterations.
Recap
A well-built internal tool starts with a clear answer to who uses it, what they do, and what the data looks like. The steps in order:
- Describe the workflow you are replacing - be specific about the current pain.
- Model the data - name every field and how records relate to each other.
- Specify roles and permissions - internal access control is more complex than it looks.
- Define forms and actions for each role's daily work - describe inputs, outputs, and what happens next.
- Build in an audit log from the start - who changed what, when, locked from editing.
- Give each role a dashboard that answers "what do I need to do right now?"
- Wire notifications to the right channels at the right moments - include time-based reminders.
- Test with real users doing real tasks before you call it ready.
- Ship against the live workflow, keep the fallback for a week, then iterate from real usage data.
The spreadsheet your team is living in is not the real problem. The real problem is that nobody built the tool yet. Now you can.
Related tutorials:

Co-founder and CTO of Creatr, building DeepBuild: the system that ships production web apps in 24 hours. Prince's open-source WhatsApp userbot, BotsApp, earned 5.5k GitHub stars and 1.3k forks during his college years. He later ran a solo freelance engineering practice to $100K in revenue before co-founding Creatr.