Need help?Jamie

Full stack web app developer in Indianapolis, Indiana

Your quotes and customer records live in spreadsheets and inboxes, or your website can’t do the one thing customers need, like logging in, paying, saving something or getting a calculated price. That’s when a web app starts to make sense. Trojan Digital Marketing builds focused web apps for small and midsize businesses from Indianapolis, Indiana: customer portals, quote calculators, admin dashboards and API integrations that need real code. We market what we build too, so people find it and use it after launch. You can try one of our apps before you call, and custom builds are quoted after a free call.

Searching for a developer job? This page is for businesses that want an app built.

Based in
Indianapolis, Indiana
App you can try today
Jev Website Scanner
Live websites we run
1,400+
Custom build price
Quoted after a free call

Or call (317) 981-2386.

The first strategy call is free, and during business hours we aim to reply within five minutes.

  1. Foundpage list saved
  2. Startedfree start, Stripe payment or included rescan
  3. Reading5 pages a step
  4. Donereport link emailed
A scan’s four states, saved in the database at every step.

Is a web app the right build for you?

Sort it by what your customer has to do on the screen. Pick the lane that sounds like your business, and its button takes you to the page that fits.

What does your customer do on screen?

  1. Customers read, then call or fill in a form

    A marketing website does this job. You need clear pages, proof and a form that reaches you.

    See website design
  2. Data moves between tools you already pay for

    Routing a form into your CRM or sending a reply after hours is automation work, set up inside the tools you have.

    See inquiry automation
  3. This page

    Someone logs in, pays, saves or calculates

    That takes a database, logins or payments, admin screens and endpoints of your own. It’s what we build here.

    What we’d build first

Where’s the line on integrations? A built-in connector, a Zap or inquiry routing belongs on our automation page. It becomes a build here once the connection holds your business rules, runs at high volume, carries sensitive data, or needs a signed webhook, its own endpoint or its own database of record. Connect the tools you already pay for

How do the four layers of a web app fit together?

Every app we build has the same four layers. The drawing is our own scanner’s stack, and each layer below says what it does there and what it would do in yours.

Our scanner’s stack, drawn from its code.
Browser · what people see and click
What it is
The screens your customers and staff use, like a login or a price that updates as they type. We build them in React and TypeScript, and pages render on the server first, so they load fast and still read without scripts.
On our scanner
The browser drives the scan. It asks the server for the next 5 pages over and over, with 2 lanes working at once, until every page is read. Close the tab and the report link picks up where it stopped.
In your app
A quote form that shows the price as the customer picks options, or a status page they open from a private link.
API · the rules
What it is
Server routes that check every request before anything touches your data. Your pricing rules, permissions and limits live here, where nobody can skip them by editing the page.
On our scanner
Each connection gets 20 site lookups, 3 free scans and 20 checkouts a day, and each email address gets 3 free scans a day and 10 a month. Cloudflare Turnstile screens out bots before a scan starts.
In your app
Your discount rules, and who’s allowed to see which jobs.
Database · what the business keeps
What it is
One place of record for jobs, quotes, customers and history. We use Cloudflare D1, which runs SQLite, and Drizzle migrations so every change to a table is written down.
On our scanner
Five tables hold scans, pages, links, daily limits and free-scan history. A unique index lets each domain claim one free scan, so two open tabs can’t both get it.
In your app
The spreadsheet your team calls “the real one”, rebuilt with statuses, a change history and an export button.

What our own apps run on

  • TypeScript
  • React 19
  • Cloudflare Workers
  • Cloudflare D1 (SQLite)
  • Drizzle ORM
  • Zod
  • Stripe
  • Resend
  • Twilio
  • Vapi
  • Turnstile

We build on that stack, and if your project needs something we don’t use, we’ll say so on the first call.

What would we build first?

Start with the one job that eats the most hours each week and build that before anything else. Pick the line that sounds like your office to see the first build, what it looks like on our side and what moves the quote.

After the free call we discuss the first build and its price. Nothing starts until you agree to the scope. See every step

What happens in your office?

We work out prices by hand
Build first
A quote calculator on your site that runs your pricing rules and emails you every quote it gives.
Like ours
Our invoice and estimate generators do exact money math in each currency’s smallest unit across 37 currencies, so a total never drifts by a rounding error.
Quote
Quoted after a free call. The number of pricing rules and options moves it most.
Staff copy the same details between systems
Build first
One endpoint that takes each record once and writes it everywhere it needs to go, with a log you can read when something doesn’t match.
Like ours
Every inquiry on this site is saved to our database before anyone gets a text or an email, and each alert is claimed once, so a retry can’t send it twice.
Quote
Quoted after a free call. Each outside system it talks to adds to it. If your tools already connect with a built-in connector, start with our automation page.
Customers call to ask where things stand
Build first
A status page each customer opens from a private link, fed by the record your team already updates.
Like ours
Every scanner report lives at its own link, and opening that link again resumes a scan that stopped.
Quote
Quoted after a free call. A private link is a smaller build than full customer logins, and we’ll tell you which one you need.
We want to take payment for something online
Build first
Stripe Checkout tied to your own records, so a paid order releases the right thing on its own and a failed payment releases nothing.
Like ours
Our scanner sells a $99 audit and $19 rescans this way. Stripe’s webhook signature is checked, and a unique index makes sure one payment pays for one scan.
Quote
Quoted after a free call. Stripe bills its own processing fees directly.
Our team runs on “the real spreadsheet”
Build first
An admin screen over a real database, with statuses and a history of every change, so nobody keeps a copy on the side.
Like ours
Our inquiry pipeline moves each lead through new, contacted, booked, won, lost or junk, and database triggers keep a history of status changes that can’t be edited.
Quote
Quoted after a free call. How many kinds of people log in moves it most.

What have we built that you can check?

Everything in this section is ours. We built it, we run it, and you can open most of it right now. None of it is a client’s app, and when we have one to show, it’ll be labeled.

Our own paid web app

What does the Jev Website Scanner do?

It reads a whole website, asks 44 questions about every page using Jev, TypeSafe’s AI model, and counts 26 technical facts in code. The first scan of a domain is free for up to 100 pages. The $99 audit reads up to 3,000 pages and scores 3 competitors you name, 25 of their pages each. We built the app around Jev, and it isn’t affiliated with or endorsed by TypeSafe.

The Jev Website Scanner start screen, with a box for a website address and a Scan my website button
The scanner’s start screen, live at /website-scan.

What happened when we scanned our own site?

We pointed the scanner at trojandigitalmarketing.com on September 25, 2026. It read 854 pages and scored 842 of them. The technical category, which code counts, averaged 99.5 out of 100. The overall health average was 63.1, because most of our pages still need writing fixes, and that fix list is the work we’re doing now.

Jev Website Scanner results for trojandigitalmarketing.com, September 25, 2026
Pages read854
Pages scored842
Rated Good115
Rated Improve727
Not scored12
Technical average99.5
Overall health average63.1

We show the unflattering number on purpose. A tool that only ever says “looks great” isn’t worth paying for.

Our own platform

What runs behind this website?

We rebuilt trojandigitalmarketing.com onto Cloudflare Workers with its own content editor and inquiry pipeline. Jeff edits and publishes without a code deploy, and search engines hear about new pages on their own. It runs on vinext, Cloudflare’s open-source framework, and the editor and pipeline on top are ours.

page routes
90+
API routes
23
database tables
19
managed redirects
117
between scheduled job runs
15 min
before a publishing key expires
90 days
See our full list of services

Leads, texts and calls

What happens when someone contacts us?

Each inquiry is saved before anyone is notified. Then Jeff gets a text through Twilio and an email through Resend, and calls our voice assistant handles on Vapi arrive as written summaries. Each alert is claimed once, so a retry can’t send it twice.

  • Statuses from new to won, with a change history that can’t be edited
  • Follow-up notes a visitor can add for 30 minutes after sending
  • A signed Resend webhook for unsubscribes, checked before it’s trusted
  • A Twilio signature check on call status updates
Send us your own test inquiry

16 free tools

Which of our tools can you use today?

Our invoice and estimate generators, PDF toolkit, PDF signing and calculators run in your browser, so your files and numbers stay on your device. The Trojan Website Checker is a Chrome extension that checks the page you have open, and its settings block it from making any network calls.

Microsite software

What is Garrison?

Garrison is the software we use to generate and update our microsite networks, branded local sites that send calls and forms straight to a business. Trojan runs more than 1,400 live websites.

See how microsite networks work

What do clients say about working with Jeff?

These reviews are about website and marketing work. We don’t have a client review of an app build yet, so none of them sits next to an app claim on this page.

“Trojan Digital Marketing gave our website a complete make over. The board members and I are absolutely thrilled!”
C. Teague McClendonAmerican Veteran Service Corp
“Oh my gosh! This is perfect! Thank you! You can always count on Trojan Digital Marketing!”
J. HollandSho.Lux Lifestyle Centre
“I had a great experience working with Jeff…”
Heather DoanGoogle review

How much does a custom web app cost?

Custom builds are quoted after a free call, in writing, because two apps with the same name can be very different jobs. Here’s what moves a quote, and the prices we do publish.

What moves the quote

  1. How many kinds of people log in. Customers and staff each need their own screens and permissions.

  2. What the app has to remember. Every table and history log is more to build and more to protect.

  3. Payments. Refunds and failed payments need handling too, beyond the checkout itself.

  4. Each outside system it talks to. Every API brings its own limits and keys.

  5. Admin screens. Somebody on your team needs a way to fix a record without calling us.

  6. Running it after launch. Hosting and outside services bill you directly, and the scope lists each one.

Free

First call

Bring the spreadsheet or the screen that slows your team down. We’ll tell you what we’d build first, or whether you should buy a tool instead.

Book the free call

$99 one time

Website audit

If your current website is the real question, the scanner’s audit scores every page up to 3,000. The first scan of a domain is free for up to 100 pages.

Start with a free scan
Read what moves the cost of a web app

What happens after the first call?

If the build fits, we discuss the scope and cost. Nothing starts until you’ve agreed to the work.

  1. You show us the job.

    Send the spreadsheet or the screen your team fights with, or call (317) 981-2386. The contact buttons on this page fill in your note for you.

  2. We talk it through, free.

    We’ll tell you whether to buy a tool, connect the ones you have or build, and you don’t commit to anything on the call.

  3. We agree on the scope and cost.

    We discuss what the first build needs to do and its price before work starts.

  4. We build it in stages you can click.

    You test a working preview as each piece lands, starting with the screen your team will use most.

  5. We launch and watch the first real use.

    Discuss postlaunch support in the scope, including who handles issues from real customers and staff.

How long does a build take?

A quote calculator and a customer portal are different sizes of job. The scope, account access, outside services and approvals affect the work. Discuss those requirements on the free call; the track below shows work order.

  1. Scope

    You: send examples and the rules you follow

    We: agree on the first build and cost

  2. First screen

    You: click through it

    We: build the screen your team uses most

  3. Data and rules

    You: check it with real cases

    We: build the database and the server rules

  4. Outside services

    You: create the accounts in your name

    We: connect payments, email or your other tools

  5. Launch

    You: tell your customers

    We: put it live and watch the first use

  6. After launch

    You: send what people ask for

    We: fix and improve from real use

The track shows work order. The build depends on the agreed scope and approvals.

Who builds your app?

You’ll work with Jeff Clerisier, who founded Trojan Digital Marketing in March 2018 and built it with no outside money. His freelance web and brand work started in 2016, and Trojan now runs more than 1,400 live websites. Jeff is your one point of contact and the person accountable for your build, from the first call to launch.

Trojan built and runs every system on this page, from the scanner to this website’s content editor and inquiry pipeline. We’re a marketing company that builds software too, so the app and the marketing that gets it used come from the same people.

Where do we draw the line?

  • We build focused web apps for small and midsize businesses. A web app works in any phone’s browser, and we don’t build native iPhone or Android apps.
  • We don’t build systems that hold regulated health records.
  • We don’t take on enterprise ERP rewrites or replace your accounting software.
  • If an existing tool does the job, we’ll tell you to buy it on the first call.

What should you read or try next?

Start with our website design page if customers only need to read and call.

What do owners ask before hiring a developer?

Is this page for hiring a developer or for developer jobs?

It’s for businesses that want a web app built. Trojan builds it for you under an agreed scope, and we don’t post developer jobs on this page.

Should we build a custom app or buy an existing tool?

Buy the tool when one fits how you work, because it’s ready today and costs less up front. Build when your pricing or process is what makes you different and every tool you’ve tried almost fits. On the free call we’ll tell you which side you’re on, and sometimes the answer is to connect two tools you already pay for.

How much does a custom web app cost?

It’s quoted after a free call, in writing. The biggest factors are how many kinds of people log in, what the app has to remember, payments, each outside system it talks to and the admin screens your team needs. Hosting and services like Stripe bill you directly after launch, and the scope lists each one.

How long does a build take?

Discuss the scope, access and approvals before work starts. We build in stages, so you can test a working screen as each piece lands.

What will you build it with?

TypeScript and React on Cloudflare Workers, with Cloudflare D1, which runs SQLite, for the database and Drizzle for table changes. Payments go through Stripe, email through Resend, and texts and calls through Twilio. It’s the stack our own scanner and this website run on, and it’s mainstream and documented, so another developer can pick it up later.

Can you connect it to QuickBooks, our CRM or another tool?

Usually, when that tool has an API that allows it. If a built-in connector or a Zap already does the job, our automation page is the better fit. We write code for the connection when it has to hold your business rules, handle high volume, protect sensitive data or check a signed webhook.

What happens when something fails after launch?

We build apps to recover on their own where it’s safe to. Our scanner tries a call to Jev up to 5 times, waiting longer after each failure, and a public scan gets 3 retries before it pauses and tells the visitor. Support after launch, and who fixes what, needs to be agreed before work starts.

Who owns the code and the accounts?

Discuss ownership before work starts, covering the code, the hosting account, the domain and outside services like Stripe. We’d rather you open accounts like Stripe in your business’s name, so the payments are yours from day one.

Do you build iPhone or Android apps?

No. We build web apps that work in any phone’s browser, so customers don’t have to install anything. If your idea truly needs an app store app, we’ll tell you on the first call.

Is Trojan based in Indianapolis?

Yes. We’re based in Indianapolis, Indiana, and our Google profile lists a service area with no street address. The apps shown on this page are our own builds.

Want to talk through your app before you decide?

Send the spreadsheet or the screen that slows your team down, plus one sentence about what you wish it did. On the free call we’ll tell you what we’d build first, or whether you should build at all.

Or call (317) 981-2386.

The first strategy call is free, and during business hours we aim to reply within five minutes.

We’re based in Indianapolis, Indiana, and build web apps for businesses across Indiana and the United States.

Keep the quote a customer accepted

A service app needs to preserve the price and job details someone agreed to. Start with one complete transaction before adding more screens.

Texas Journeyman Prep hours calculator with license choices and planning fields
An existing calculator interface places inputs beside an explanation of the calculation. Use this front-end example when discussing the information a workflow screen needs. View the project
Hypothetical example A small service business in Indianapolis, Indiana moves from an estimate to a booked visit

Before

  • The office emails an estimate for a two hour visit. The customer agrees, then asks for an extra task by text. A staff member changes the spreadsheet price. Nobody can see which version the customer accepted.
  • A field worker opens yesterday's attachment while the office reads today's row. Both act in good faith, but each sees a different job. The app's first job would be to keep those versions clear.

After

  • We'd give each estimate its own reference and save the accepted version. Later changes become a new version with a fresh acceptance step. The booked visit points to the version that governs that work.
  • Our first test would follow that record through a change, a cancellation and a return visit. We can judge the screen by whether staff can answer what was agreed without searching a text thread.

Bring one ordinary job and one awkward exception to the first conversation. Remove private details from both. We can use them to test the rules: who may edit a price, when approval expires, and how a changed date affects the booking. A polished screen can't settle a rule the business hasn't agreed on.

Give each business record a clear home

Choose which system controls each field before connecting tools. Otherwise a corrected phone number or unpaid invoice can change back during the next sync.

Possible field ownership for the same hypothetical service office
RecordWhere the rule livesWhat another tool receives
Customer contactThe agreed customer record controls the current phone number. We keep its stable identifier when a name changes.A connected scheduler receives the identifier and current contact fields, with a defined way to flag a failed update.
Accepted estimateThe app stores its saved price version and the acceptance event. Editing a draft doesn't alter a booked job.The office sees the accepted total and version reference. Our connection avoids treating an email attachment as the current record.
Invoice balanceThe accounting system remains responsible for its ledger. A portal may display a balance received from that system.The customer sees when the displayed balance was refreshed and can ask the office about a mismatch.
Service boundaryYour own operating rules define the addresses you serve. We ask how staff handle an address near that boundary.A booking screen checks the job address against those rules before offering a visit.

Before moving old rows, choose what deserves to come across. Closed jobs may need history without active booking controls. We ask how your team spots duplicate customers and which details must stay attached to each visit. Try the import with a small sample that includes a renamed customer and a corrected address. Check the result with the person who maintains those records now.

Define access by the action staff can take

A private office screen should answer who may see, change or approve each record. A job title by itself leaves too many gaps.

Should every employee see the whole customer file?
Map the task first. A field worker might need an address and visit notes without access to billing history. We ask which fields each role needs, including shared devices and temporary staff. Our design should make that boundary clear on the screen and enforce it when a record is requested.
What happens when someone changes roles or leaves?
The owner needs a way to remove access and identify any shared logins still in use. We'd test a disabled account against saved links and attempted edits. A former worker's name can remain in the job history without giving that person continued access to it.
Can the office correct mistakes without erasing the trail?
Allow the correction your team needs, while recording who made it and what changed. We can discuss a separate approval for refunds or price overrides. That keeps an ordinary typo fix quick while giving larger changes a deliberate checkpoint.

Decide what happens when a connection stops

A failed connection needs a visible state and a safe way to try again. Plan for that state while the normal path is still simple.

  1. Save the business event For the sample booking, we'd keep the agreed visit in the app before sending an outside notification. Staff should be able to find that booking even if the message service is unavailable.
  2. Track the attempted send Record which event caused the message and which destination it used. Our support screen can then distinguish an unsent confirmation from a customer who entered the wrong email address.
  3. Make a repeated attempt safe Ask what would happen if the same event reached the receiving tool twice. We need a way to recognize an already completed booking, invoice or message before creating another one.
  4. Give staff a recovery route A named person should know where failed sends appear and when a manual call is needed. We'd test a retry that succeeds and one that still fails, including the wording staff see.

Treat an integration as a small operating agreement between two systems. Which direction do edits travel? What counts as complete? Who handles a rejected record? Our questions should cover expired access keys, missing fields and changed account settings. Each answer affects the work needed after the first successful connection.

Keep payment status separate from job status

A paid deposit and a confirmed appointment describe different things. Keeping them separate helps staff handle rescheduling, refunds and a customer who closes checkout early.

  • Define what a deposit pays for and when the visit becomes confirmed. We'd ask whether staff may hold a slot while payment is pending, and how that hold ends.
  • Let the server determine the payable amount from the accepted estimate. Our test should include an attempt to submit an altered total from the browser.
  • Choose the trusted payment record that lets the job move forward. A return to the website alone should never be the proof that money arrived.
  • Show a pending state when confirmation hasn't arrived. Tell the customer how to check it without placing another order. We should test refreshes and repeat button presses.
  • Separate a refund from a cancellation. A cancelled visit may still need a fee handled under your agreed terms. Our staff screen should show the reason for each action.

Avoid collecting payment details in a general notes box. Use the payment provider's intended checkout flow and define what the app needs to retain. We can test with the provider's test environment before live payments. Ask about partial refunds, disputed payments and access to receipts, because each creates a different office task.

Make a failed form easy to finish

A customer should be able to fix a rejected field without starting again. This matters most in the booking and payment paths where a mistake blocks progress.

Texas Electrician Exam box fill lab with item buttons and a running calculation
The box fill project shows button controls and visible calculation feedback. The next step is to test those interactions with the people who will use them. View the project
  • Name the field that needs attention and explain the fix. We can compare a vague error with a message that asks for a complete service address.
  • Keep valid entries while the customer corrects one problem. Our check should include a long visit note, so a failed date entry doesn't erase that work.
  • Allow the booking controls to work by keyboard. Test moving through fields, selecting a date and dismissing a dialog while the pointer stays untouched.
  • Make changed results available to screen readers. We'd check what is announced when a price recalculates or a saved booking receives its confirmation.
  • Check submitted values on the server too. Browser feedback can help someone enter data, but it doesn't replace checks at the point where the business record is saved.

Test the awkward office cases before launch

Use business examples to judge a working app. The goal is to check the saved record and staff response alongside what a customer sees.

Acceptance cases for the hypothetical visit booking
Try thisWhat the business should check
Accept an older estimateThe app either accepts the valid saved version or explains why it expired. Our test must never silently substitute a newer price.
Open the same job in two tabsA later save doesn't quietly erase a newer change. Staff can understand a conflict and choose the right next action.
Lose the connection after submittingA returning customer can check whether the booking exists. We inspect the record before asking them to send it again.
Remove a staff member's accessThe removed account can't read or change the job through a saved link. We test the request as well as the menu.
Send the same payment notice twiceOne payment still belongs to one job. The second notice doesn't create another appointment or send an extra charge.

Ask the person who handles difficult calls to try these cases. Their questions often expose missing rules faster than a larger feature list. We can use invented customers and sample amounts for testing. Keep real customer information out of a preview until its access and handling rules have been agreed.

Plan the app's upkeep and your exit options

Account control, data exports and ordinary fixes belong in the buying conversation. They affect whether your business can keep using the app when people or providers change.

Start by naming the business owner of each account and the person who can recover access. Include the domain and billing contacts. We should also discuss how customer and job records leave the system. A file export has limited value if the receiving team can't understand its fields or connect estimates to visits.

Ask how a saved backup would become a working service again. An export and a tested recovery process answer different questions. We'd want the responsible people to know which accounts and settings are needed, as well as where the records sit. If a new developer took over, our handoff discussion should cover the app's business rules and the outside tools those rules depend on.

  • Compare a smaller custom tool with a broader replacement. Our sample office could keep its accounting package and build only the estimate acceptance step, reducing the number of records to move.
  • Agree which changes staff can make themselves. A new appointment type might be routine, while a changed deposit rule deserves testing before customers see it.
  • Ask who watches failed background work and who handles urgent faults. We can discuss support responsibilities without pretending every app needs the same service arrangement.
  • Try a sample export before relying on it. Check that record references, dates and amounts still make sense when opened outside the app. We'd include the accepted quote version.
  • Bring the task your team repeats and the exception that causes trouble. Those two examples give us a concrete starting point for deciding whether a focused build earns its place.

Sources

Read more on this