---
title: Grubhub Clone Features
description: 
url: https://miracuves.com/grubhub-clone/features
date_modified: 2026-09-10
author: miracuves
language: en_US
---

.mcv-ghf{
    --crimson:#e8344f; --crimson-deep:#a70d2a; --crimson-hot:#d81b46; --crimson-light:#ff8090;
    --amber:#fbbf24; --black:#0a0a0a; --white:#ffffff; --paper:#faf8f8; --ink:#191419; --ink-dim:#6d666d;
    --line:rgba(11,11,16,0.1); --line-light:rgba(255,255,255,0.12);
    --card-bg:rgba(8,3,8,0.82);
    font-family:'Plus Jakarta Sans',Arial,sans-serif; color:var(--ink); background:var(--white); margin:0; padding:0;
  }
  .mcv-ghf *{ box-sizing:border-box; }
  .mcv-ghf h1,.mcv-ghf h2,.mcv-ghf h3{ font-family:'Plus Jakarta Sans',Arial,sans-serif; font-weight:800; margin:0; letter-spacing:-0.02em; line-height:1.12; }
  .mcv-ghf p{ margin:0 0 14px; line-height:1.7; color:var(--ink); }
  .mcv-ghf a{ color:var(--crimson-deep); text-decoration:none; }
  .mcv-ghf .mono{ font-family:'JetBrains Mono',monospace; }
  .mcv-ghf-wrap{ max-width:1180px; margin:0 auto; padding:0 24px; position:relative; z-index:2; }
  .mcv-ghf-bleed{ position:relative; left:50%; right:50%; margin-left:-50vw; margin-right:-50vw; width:100vw; }

  .mcv-seo-ref{ background:#FFF7E0; border:2px dashed #C79A00; padding:18px 22px; font-family:Arial,sans-serif; font-size:13px; color:#4A3B00; max-width:1180px; margin:18px auto; border-radius:8px; }

  .mcv-ghf-crumb{ display:flex; gap:8px; align-items:center; font-family:'JetBrains Mono',monospace; font-size:11.5px; color:rgba(255,255,255,.62); margin-bottom:20px; }
  .mcv-ghf-crumb a{ color:rgba(255,255,255,.62); }
  .mcv-ghf-crumb a:hover{ color:var(--crimson-light); }
  .mcv-ghf-crumb span.sep{ opacity:.5; }
  .mcv-ghf-crumb span.cur{ color:rgba(255,255,255,.75); }

  .mcv-ghf-eyebrow{ display:inline-flex; align-items:center; gap:8px; padding:7px 16px; border-radius:100px; background:rgba(255,255,255,.06); border:1px solid var(--line-light); font-family:'JetBrains Mono',monospace; font-size:11.5px; font-weight:700; letter-spacing:.18em; text-transform:uppercase; color:var(--crimson-light); margin-bottom:22px; }
  .mcv-ghf-eyebrow .dot{ width:6px; height:6px; border-radius:50%; background:var(--crimson); }

  .mcv-ghf-hero{ background:radial-gradient(ellipse 900px 500px at 85% -10%, rgba(232,52,79,.16), transparent), #0a0a0a; color:#fff; padding:56px 0 150px; position:relative; overflow:hidden; }
  .mcv-ghf-hero .ring{ position:absolute; border:2px solid rgba(232,52,79,.18); border-radius:50%; pointer-events:none; }
  .mcv-ghf-hero .ring1{ width:560px; height:560px; top:-260px; right:-200px; }
  .mcv-ghf-hero .ring2{ width:340px; height:340px; bottom:-200px; right:120px; border-color:rgba(232,52,79,.1); }
  .mcv-ghf-herogrid{ display:grid; grid-template-columns:1.1fr 0.9fr; gap:48px; align-items:center; }
  .mcv-ghf-hero h1{ font-size:clamp(27px,3.9vw,44px); color:#fff; }
  .mcv-ghf-hero h1 em{ font-style:normal; color:#ff8090; }
  .mcv-ghf-hero p.sub{ font-size:16px; color:rgba(255,255,255,.68); max-width:600px; margin:20px 0 30px; }

  .mcv-ghf a.mcv-ghf-btn{ display:inline-flex; align-items:center; gap:8px; border-radius:12px; background:linear-gradient(160deg,#d81b46,#e6223f); color:#fff; font-weight:700; font-size:15px; padding:15px 28px; box-shadow:0 10px 30px rgba(232,52,79,.3); transition:transform .25s cubic-bezier(.2,.8,.2,1), box-shadow .25s; }
  .mcv-ghf a.mcv-ghf-btn:hover{ color:#fff; transform:translateY(-2px); box-shadow:0 14px 36px rgba(232,52,79,.42); text-decoration:none; }
  .mcv-ghf a.mcv-ghf-btn-outline{ display:inline-flex; align-items:center; border:2px solid rgba(255,255,255,.7); color:#fff; border-radius:12px; font-weight:700; font-size:15px; padding:13px 26px; margin-left:12px; transition:all .2s; }
  .mcv-ghf a.mcv-ghf-btn-outline:hover{ background:#fff; color:#191419; text-decoration:none; }

  .mcv-ghf-trust{ display:flex; flex-wrap:wrap; gap:22px; margin-top:34px; padding-top:24px; border-top:1px solid var(--line-light); }
  .mcv-ghf-trust-item{ display:flex; align-items:center; gap:8px; font-size:12.5px; color:rgba(255,255,255,.6); }
  .mcv-ghf-trust-item strong{ font-family:'JetBrains Mono',monospace; color:#fff; font-size:14px; }

  .mcv-ghf-cardstack{ position:relative; height:340px; }
  .mcv-ghf-fincard{ position:absolute; width:300px; height:180px; border-radius:18px; padding:22px; background:linear-gradient(150deg,#1c1418,#0d0709); border:1px solid var(--line-light); box-shadow:0 30px 70px rgba(0,0,0,.5); }
  .mcv-ghf-fincard.c1{ top:0; left:10px; z-index:1; opacity:.5; transform:rotate(-6deg) scale(.92); }
  .mcv-ghf-fincard.c2{ top:30px; left:40px; z-index:2; background:linear-gradient(150deg,#3a0a15,#160408 60%,#0a0a0a); border-color:rgba(232,52,79,.3); box-shadow:0 40px 90px rgba(0,0,0,.55), 0 0 60px -12px rgba(232,52,79,.35); }
  .mcv-ghf-fincard .brand{ font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:rgba(255,255,255,.55); }
  .mcv-ghf-fincard .chip{ width:34px; height:24px; border-radius:5px; background:linear-gradient(135deg,#ff8090,#e8344f); margin:22px 0 18px; }
  .mcv-ghf-fincard .num{ font-family:'JetBrains Mono',monospace; font-size:15px; color:#fff; letter-spacing:.1em; }
  .mcv-ghf-fincard .curr{ position:absolute; bottom:22px; right:22px; font-family:'JetBrains Mono',monospace; font-size:11px; color:#ff8090; }
  .mcv-ghf-float{ position:absolute; background:rgba(8,3,8,0.82); border:1px solid var(--line-light); border-radius:14px; padding:12px 16px; box-shadow:0 16px 40px rgba(0,0,0,.35); z-index:3; }
  .mcv-ghf-float .k2{ font-family:'JetBrains Mono',monospace; font-size:10px; color:#ff8090; text-transform:uppercase; letter-spacing:.08em; margin-bottom:3px; }
  .mcv-ghf-float .v{ font-family:'JetBrains Mono',monospace; font-size:15px; color:#fff; font-weight:700; }
  .mcv-ghf-float-1{ top:-10px; right:0; }
  .mcv-ghf-float-2{ bottom:10px; left:0; }

  .mcv-ghf-statbar{ margin-top:-72px; position:relative; z-index:3; }
  .mcv-ghf-statbar .inner{ background:rgba(8,3,8,0.82); border:1px solid var(--line-light); border-radius:18px; box-shadow:0 24px 60px rgba(0,0,0,.35); padding:32px 20px; display:grid; grid-template-columns:repeat(4,1fr); }
  .mcv-ghf-statbar .stat{ text-align:center; padding:0 12px; border-right:1px solid var(--line-light); }
  .mcv-ghf-statbar .stat:last-child{ border-right:none; }
  .mcv-ghf-statbar .num{ font-family:'JetBrains Mono',monospace; font-weight:700; font-size:22px; color:#ff8090; }
  .mcv-ghf-statbar .lbl{ font-size:11.5px; color:rgba(255,255,255,.62); margin-top:6px; line-height:1.4; }

  .mcv-ghf-section{ padding:100px 0 76px; }
  .mcv-ghf-section.paper{ background:#faf8f8; }
  .mcv-ghf-section.tight{ padding-top:76px; }
  .mcv-ghf-head{ text-align:center; max-width:720px; margin:0 auto 48px; }
  .mcv-ghf-head .kicker{ font-family:'JetBrains Mono',monospace; font-size:12px; font-weight:700; letter-spacing:.18em; text-transform:uppercase; color:#a70d2a; margin-bottom:12px; }
  .mcv-ghf-head h2{ font-size:clamp(22px,3vw,34px); color:#191419; }
  .mcv-ghf-head p{ color:#6d666d; margin-top:14px; }

  .mcv-ghf-rolegrid{ display:grid; grid-template-columns:repeat(3,1fr); gap:22px; }
  .mcv-ghf-rolecard{ background:#fff; border:1px solid var(--line); border-radius:18px; padding:28px 24px; box-shadow:0 6px 18px rgba(0,0,0,.05); transition:transform .3s cubic-bezier(.2,.8,.2,1), box-shadow .3s, border-color .3s; }
  .mcv-ghf-rolecard:hover{ transform:translateY(-6px); box-shadow:0 20px 40px rgba(0,0,0,.09); border-color:#e8344f; }
  .mcv-ghf-roleicon{ width:40px; height:40px; border-radius:10px; background:rgba(232,52,79,.12); border:1px solid rgba(232,52,79,.3); display:flex; align-items:center; justify-content:center; margin-bottom:16px; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:14px; color:#a70d2a; }
  .mcv-ghf-rolecard h3{ font-size:17px; margin-bottom:12px; color:#191419; }
  .mcv-ghf-rolecard ul{ margin:0; padding-left:18px; font-size:13.5px; color:#191419; }
  .mcv-ghf-rolecard li{ margin-bottom:8px; line-height:1.5; }

  .mcv-ghf-tablewrap{ overflow-x:auto; border-radius:16px; box-shadow:0 12px 34px rgba(0,0,0,.07); border:1px solid var(--line); }
  table.mcv-ghf-table{ border-collapse:collapse; width:100%; min-width:680px; background:#fff; font-size:13.5px; }
  table.mcv-ghf-table th{ background:#0a0a0a; color:#ffffff; text-align:left; padding:14px 16px; font-family:'JetBrains Mono',monospace; font-weight:600; font-size:12px; letter-spacing:.04em; text-transform:uppercase; }
  table.mcv-ghf-table td{ padding:14px 16px; border-bottom:1px solid rgba(11,11,16,0.1); vertical-align:top; color:#191419; }
  table.mcv-ghf-table td.hl{ background:rgba(232,52,79,.06); border-top:3px solid #e8344f; font-weight:600; color:#191419; }
  table.mcv-ghf-table th.hl{ background:#e6223f; color:#ffffff; }
  table.mcv-ghf-table tbody tr:hover td{ background:#f4f1f1; color:#191419; }
  table.mcv-ghf-table tbody tr:hover td.hl{ background:rgba(232,52,79,.13); color:#191419; }
  table.mcv-ghf-table tr:last-child td{ border-bottom:none; }
  .mcv-ghf-note{ font-size:12.5px; color:#6d666d; margin-top:12px; }

  .mcv-ghf-callout{ background:linear-gradient(135deg,#2B0710,#4A0F1E); color:#fff; border-radius:20px; padding:40px 44px; }
  .mcv-ghf-callout h2,.mcv-ghf-callout h3{ color:#fff; font-size:22px; margin-bottom:12px; }
  .mcv-ghf-callout p{ color:rgba(255,255,255,.78); font-size:14.5px; margin:0; }

  .mcv-ghf-honest{ background:#fff; border:1px solid var(--line); border-left:4px solid #fbbf24; border-radius:14px; padding:28px 30px; }
  .mcv-ghf-honest h3{ font-size:17px; margin-bottom:14px; color:#191419; }
  .mcv-ghf-honestgrid{ display:grid; grid-template-columns:1fr 1fr; gap:10px 28px; }
  .mcv-ghf-honestgrid div{ font-size:13.5px; color:#191419; line-height:1.55; padding-left:18px; position:relative; }
  .mcv-ghf-honestgrid div::before{ content:'!'; position:absolute; left:0; top:0; font-family:'JetBrains Mono',monospace; font-weight:700; color:#8a6100; }

  .mcv-ghf-cs{ background:#fff; border:1px solid var(--line); border-radius:20px; padding:32px 34px; display:flex; justify-content:space-between; align-items:center; gap:24px; flex-wrap:wrap; box-shadow:0 8px 24px rgba(0,0,0,.05); }
  .mcv-ghf-cs-badge{ display:inline-flex; align-items:center; gap:7px; padding:6px 14px; border-radius:100px; background:rgba(232,52,79,.08); border:1px solid rgba(232,52,79,.25); font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:#a70d2a; margin-bottom:12px; }
  .mcv-ghf-cs-badge .dot{ width:6px; height:6px; border-radius:50%; background:#e8344f; }
  .mcv-ghf-cs-body{ flex:1; min-width:260px; }
  .mcv-ghf-cs-body h3{ font-size:16.5px; margin-bottom:6px; color:#191419; }
  .mcv-ghf-cs-body p{ color:#6d666d; font-size:13.5px; margin:0; max-width:460px; }
  .mcv-ghf a.mcv-ghf-cs-link{ font-family:'JetBrains Mono',monospace; font-size:12px; font-weight:700; color:#a70d2a; white-space:nowrap; }

  .mcv-ghf-faqgrid{ display:grid; grid-template-columns:1fr 1fr; gap:0 40px; max-width:1000px; margin:0 auto; }
  .mcv-ghf-faq details{ border-bottom:1px solid var(--line); padding:18px 0; }
  .mcv-ghf-faq summary{ font-family:'Plus Jakarta Sans',Arial,sans-serif; font-weight:700; font-size:15px; color:#191419; cursor:pointer; list-style:none; display:flex; justify-content:space-between; align-items:center; gap:16px; }
  .mcv-ghf-faq summary::-webkit-details-marker{ display:none; }
  .mcv-ghf-faq summary::after{ content:'+'; font-family:'JetBrains Mono',monospace; color:#a70d2a; font-size:20px; font-weight:700; flex:none; }
  .mcv-ghf-faq details[open] summary::after{ content:'\2212'; }
  .mcv-ghf-faq .a{ color:#6d666d; font-size:13.5px; margin-top:10px; line-height:1.65; }

  .mcv-ghf-cta{ background:linear-gradient(120deg,#e6223f,#6e0e1f); color:#fff; padding:64px 0; position:relative; overflow:hidden; }
  .mcv-ghf-cta .ring{ position:absolute; border:2px solid rgba(255,255,255,.14); border-radius:50%; width:360px; height:360px; top:-140px; right:-100px; }
  .mcv-ghf-cta .flex{ display:flex; justify-content:space-between; align-items:center; gap:28px; flex-wrap:wrap; position:relative; z-index:2; }
  .mcv-ghf-cta h2{ color:#fff; font-size:clamp(20px,2.6vw,28px); margin-bottom:8px; }
  .mcv-ghf-cta p{ color:#ffffff; margin:0; max-width:460px; }
  .mcv-ghf-cta a.mcv-ghf-btn-outline{ border-color:#fff; }
  .mcv-ghf-cta a.mcv-ghf-btn{ background:#fff; box-shadow:0 10px 30px rgba(0,0,0,.2); }
  .mcv-ghf-cta a.mcv-ghf-btn,.mcv-ghf-cta a.mcv-ghf-btn:hover{ color:#a70d2a; }

  .mcv-ghf-explore{ display:flex; flex-wrap:wrap; gap:10px; justify-content:center; }
  .mcv-ghf a.mcv-ghf-pill{ font-family:'JetBrains Mono',monospace; font-size:12.5px; font-weight:600; padding:10px 18px; border-radius:100px; border:1px solid var(--line); color:#191419; background:#fff; transition:all .2s; }
  .mcv-ghf a.mcv-ghf-pill:hover{ border-color:#e8344f; color:#a70d2a; text-decoration:none; }
  .mcv-ghf a.mcv-ghf-pill.cur{ background:#191419; color:#fff; border-color:#191419; }

  .mcv-ghf-finalcta{ background:#0a0a0a; color:#fff; text-align:center; padding:96px 24px 64px; position:relative; overflow:hidden; }
  .mcv-ghf-finalcta .ring{ position:absolute; border:1.5px solid rgba(232,52,79,.16); border-radius:50%; }
  .mcv-ghf-finalcta .ring1{ width:480px; height:480px; top:-220px; left:-160px; }
  .mcv-ghf-finalcta .ring2{ width:300px; height:300px; bottom:-180px; right:-90px; }
  .mcv-ghf-finalcta .card{ background:rgba(8,3,8,0.82); border:1px solid var(--line-light); border-radius:24px; padding:56px 40px; max-width:720px; margin:0 auto; position:relative; z-index:2; }
  .mcv-ghf-finalcta h2{ color:#fff; font-size:clamp(24px,3.2vw,34px); max-width:640px; margin:0 auto 14px; }
  .mcv-ghf-finalcta p.sub{ color:rgba(255,255,255,.7); max-width:520px; margin:0 auto 30px; }
  .mcv-ghf-footerbar{ max-width:1180px; margin:56px auto 0; padding-top:28px; border-top:1px solid var(--line-light); position:relative; z-index:2; }
  .mcv-ghf-byline{ display:flex; flex-wrap:wrap; gap:6px 14px; align-items:center; font-family:'JetBrains Mono',monospace; font-size:11.5px; color:rgba(255,255,255,.55); border-bottom:1px solid rgba(255,255,255,.12); padding-bottom:16px; margin-bottom:12px; }
  .mcv-ghf-byline strong{ color:#fff; font-weight:600; }
  .mcv-ghf-byline .dotsep{ opacity:.4; }
  .mcv-ghf-footermeta{ display:flex; flex-wrap:wrap; justify-content:space-between; gap:12px; font-family:'JetBrains Mono',monospace; font-size:11px; color:rgba(255,255,255,.55); }

  @media (max-width:900px){
    .mcv-ghf-herogrid{ grid-template-columns:1fr; }
    .mcv-ghf-statbar .inner{ grid-template-columns:repeat(2,1fr); gap:18px 0; }
    .mcv-ghf-statbar .stat:nth-child(2){ border-right:none; }
    .mcv-ghf-rolegrid{ grid-template-columns:1fr; }
    .mcv-ghf-honestgrid{ grid-template-columns:1fr; }
    .mcv-ghf-faqgrid{ grid-template-columns:1fr; }
    .mcv-ghf-hero h1{ font-size:27px; }
    .mcv-ghf-cta .flex{ flex-direction:column; align-items:flex-start; }
    .mcv-ghf-cardstack{ height:260px; }
    .mcv-ghf-fincard{ width:250px; height:150px; }
  }
  @media (prefers-reduced-motion: reduce){ .mcv-ghf *{ animation:none !important; transition:none !important; } }
  /* --- components used by cost / company / business-model --- */
  .mcv-ghf-pricecard{ background:linear-gradient(150deg,#3a0a15,#160408 60%,#0a0a0a); border:1px solid rgba(232,52,79,.3); border-radius:22px; padding:34px 32px; box-shadow:0 40px 90px rgba(0,0,0,.55), 0 0 60px -12px rgba(232,52,79,.35); }
  .mcv-ghf-pricecard .plan{ font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.16em; text-transform:uppercase; color:#ff8090; margin-bottom:14px; }
  .mcv-ghf-pricecard .amt{ font-family:'JetBrains Mono',monospace; font-size:44px; font-weight:700; color:#fff; line-height:1; }
  .mcv-ghf-pricecard .per{ font-size:13px; color:rgba(255,255,255,.6); margin-top:8px; }
  .mcv-ghf-pricecard ul{ margin:22px 0 0; padding-left:18px; color:rgba(255,255,255,.78); font-size:13.5px; }
  .mcv-ghf-pricecard li{ margin-bottom:8px; line-height:1.5; }
  .mcv-ghf-drivers{ display:grid; grid-template-columns:repeat(3,1fr); gap:22px; }
  .mcv-ghf-driver{ background:#fff; border:1px solid rgba(11,11,16,0.1); border-radius:18px; padding:26px 24px; box-shadow:0 6px 18px rgba(0,0,0,.05); transition:transform .3s cubic-bezier(.2,.8,.2,1), box-shadow .3s, border-color .3s; }
  .mcv-ghf-driver:hover{ transform:translateY(-6px); box-shadow:0 20px 40px rgba(0,0,0,.09); border-color:#e8344f; }
  .mcv-ghf-driver h3{ font-size:16px; margin-bottom:10px; color:#191419; }
  .mcv-ghf-driver p{ font-size:13.5px; color:#6d666d; margin:0; }
  .mcv-ghf-steps{ display:grid; grid-template-columns:repeat(3,1fr); gap:18px; }
  .mcv-ghf-step{ background:#fff; border:1px solid rgba(11,11,16,0.1); border-radius:16px; padding:24px 22px; }
  .mcv-ghf-step .n{ font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:#a70d2a; margin-bottom:8px; }
  .mcv-ghf-step h3{ font-size:15.5px; margin-bottom:8px; color:#191419; }
  .mcv-ghf-step p{ font-size:13.5px; color:#6d666d; margin:0; }
  .mcv-ghf-checkgrid{ display:grid; grid-template-columns:1fr 1fr; gap:16px 28px; }
  .mcv-ghf-check{ background:#fff; border:1px solid rgba(11,11,16,0.1); border-radius:14px; padding:20px 22px; }
  .mcv-ghf-check h3{ font-size:15px; margin-bottom:8px; color:#191419; }
  .mcv-ghf-check p{ font-size:13.5px; color:#6d666d; margin:0; }
  .mcv-ghf-flags{ display:grid; grid-template-columns:1fr 1fr; gap:14px 28px; }
  .mcv-ghf-flag{ font-size:13.5px; color:#191419; line-height:1.55; padding-left:22px; position:relative; }
  .mcv-ghf-flag::before{ content:'\2715'; position:absolute; left:0; top:0; font-family:'JetBrains Mono',monospace; font-weight:700; color:#a70d2a; }
  .mcv-ghf-pt{ background:radial-gradient(ellipse 800px 400px at 20% 0%, rgba(232,52,79,.14), transparent), #0a0a0a; color:#fff; padding:92px 0 84px; }
  .mcv-ghf-pt .mcv-ghf-head h2{ color:#fff; }
  .mcv-ghf-pt .mcv-ghf-head p{ color:rgba(255,255,255,.68); }
  .mcv-ghf-pt .mcv-ghf-head .kicker{ color:#ff8090; }
  .mcv-ghf-ptgrid{ display:grid; grid-template-columns:repeat(3,1fr); gap:20px; }
  .mcv-ghf-ptcard{ background:rgba(8,3,8,0.82); border:1px solid rgba(255,255,255,0.12); border-radius:18px; padding:26px 24px; }
  .mcv-ghf-ptcard h3{ font-size:15.5px; color:#fff; margin-bottom:10px; }
  .mcv-ghf-ptcard p{ font-size:13.5px; color:rgba(255,255,255,.72); margin:0; }
  .mcv-ghf-ptcard .tag{ display:inline-block; font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.1em; text-transform:uppercase; color:#ff8090; border:1px solid rgba(232,52,79,.35); border-radius:100px; padding:3px 10px; margin-bottom:12px; }
  .mcv-ghf-csbox{ background:#fff; border:1px solid rgba(11,11,16,0.1); border-radius:22px; padding:40px 42px; box-shadow:0 12px 34px rgba(0,0,0,.06); }
  .mcv-ghf-csmeta{ display:flex; flex-wrap:wrap; gap:26px; margin:22px 0 26px; padding:20px 0; border-top:1px solid rgba(11,11,16,0.1); border-bottom:1px solid rgba(11,11,16,0.1); }
  .mcv-ghf-csmeta div{ font-size:13px; color:#6d666d; }
  .mcv-ghf-csmeta strong{ display:block; font-family:'JetBrains Mono',monospace; font-size:18px; color:#191419; margin-bottom:2px; }
  .mcv-ghf-cscols{ display:grid; grid-template-columns:repeat(3,1fr); gap:26px; }
  .mcv-ghf-cscols h4{ font-size:13px; font-family:'JetBrains Mono',monospace; letter-spacing:.08em; text-transform:uppercase; color:#a70d2a; margin:0 0 10px; }
  .mcv-ghf-cscols ul{ margin:0; padding-left:18px; font-size:13.5px; color:#191419; }
  .mcv-ghf-cscols li{ margin-bottom:8px; line-height:1.5; }
  .mcv-ghf-quote{ margin-top:28px; padding:24px 26px; background:#faf8f8; border-left:3px solid #e8344f; border-radius:0 12px 12px 0; }
  .mcv-ghf-quote p{ font-size:15px; font-style:italic; color:#191419; margin:0 0 10px; }
  .mcv-ghf-quote .who{ font-family:'JetBrains Mono',monospace; font-size:12px; color:#6d666d; font-style:normal; }
  .mcv-ghf-revgrid{ display:grid; grid-template-columns:repeat(3,1fr); gap:22px; }
  .mcv-ghf-revcard{ background:#fff; border:1px solid rgba(11,11,16,0.1); border-radius:18px; padding:28px 24px; box-shadow:0 6px 18px rgba(0,0,0,.05); transition:transform .3s cubic-bezier(.2,.8,.2,1), box-shadow .3s, border-color .3s; }
  .mcv-ghf-revcard:hover{ transform:translateY(-6px); box-shadow:0 20px 40px rgba(0,0,0,.09); border-color:#e8344f; }
  .mcv-ghf-revcard .n{ font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:#a70d2a; margin-bottom:10px; }
  .mcv-ghf-revcard h3{ font-size:16.5px; margin-bottom:10px; color:#191419; }
  .mcv-ghf-revcard p{ font-size:13.5px; color:#6d666d; margin:0; }
  .mcv-ghf-revcard .core{ display:inline-block; margin-top:14px; font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.1em; text-transform:uppercase; color:#a70d2a; background:rgba(232,52,79,.08); border:1px solid rgba(232,52,79,.25); border-radius:100px; padding:3px 10px; }
  .mcv-ghf-disclose{ background:#faf8f8; border:1px dashed rgba(11,11,16,0.1); border-radius:14px; padding:26px 28px; max-width:860px; margin:0 auto; }
  .mcv-ghf-disclose h3{ font-size:16px; margin-bottom:10px; color:#191419; }
  .mcv-ghf-disclose p{ font-size:13.5px; color:#6d666d; margin:0 0 10px; }
  .mcv-ghf-disclose p:last-child{ margin-bottom:0; }
  .mcv-ghf-callout .figs{ display:flex; flex-wrap:wrap; gap:32px; margin-top:22px; padding-top:20px; border-top:1px solid rgba(255,255,255,0.12); }
  .mcv-ghf-callout .figs div{ font-size:12.5px; color:rgba(255,255,255,.65); }
  .mcv-ghf-callout .figs strong{ display:block; font-family:'JetBrains Mono',monospace; font-size:20px; color:#fff; margin-bottom:3px; }
  @media (max-width:900px){
    .mcv-ghf-drivers,.mcv-ghf-steps,.mcv-ghf-checkgrid,.mcv-ghf-flags,.mcv-ghf-ptgrid,.mcv-ghf-cscols,.mcv-ghf-revgrid{ grid-template-columns:1fr; }
    .mcv-ghf-csbox{ padding:28px 24px; }
  }
  /* ===== components ported from the shipped reference bundle (instagram-clone) ===== */
  .mcv-ghf-aside{ border-left:3px solid #e8344f; background:#faf8f8; border-radius:0 16px 16px 0; padding:32px 36px; }
  .mcv-ghf-aside h3{ font-size:17px; margin-bottom:14px; color:#191419; }
  .mcv-ghf-aside ul{ margin:0; padding:0; list-style:none; display:grid; grid-template-columns:1fr 1fr; gap:16px 32px; }
  .mcv-ghf-aside li{ padding-left:18px; position:relative; font-size:14px; color:#191419; line-height:1.6; }
  .mcv-ghf-aside li::before{ content:''; position:absolute; left:0; top:7px; width:7px; height:7px; background:#e8344f; transform:rotate(45deg); }
  .mcv-ghf-aside li span{ color:#6d666d; display:block; font-size:12.5px; margin-top:2px; }
  .mcv-ghf-flowrow{ display:grid; grid-template-columns:64px 1fr; gap:22px; padding:28px 0; border-bottom:1px solid rgba(11,11,16,0.1); align-items:start; }
  .mcv-ghf-flowrow:last-child{ border-bottom:none; }
  .mcv-ghf-flowrow h3{ font-size:18px; margin-bottom:8px; color:#191419; }
  .mcv-ghf-flowrow p{ color:#6d666d; font-size:14.5px; margin:0; max-width:760px; }
  .mcv-ghf-flownum{ width:56px; height:56px; border-radius:50%; border:1.5px solid rgba(11,11,16,0.1); display:flex; align-items:center; justify-content:center; font-family:'JetBrains Mono',monospace; font-weight:700; color:#a70d2a; font-size:16px; }
  .mcv-ghf-icongrid{ display:grid; grid-template-columns:repeat(2,1fr); gap:20px; }
  .mcv-ghf-iconitem{ background:#fff; border:1px solid rgba(11,11,16,0.1); border-radius:14px; padding:22px 24px; display:flex; gap:14px; align-items:flex-start; box-shadow:0 6px 18px rgba(0,0,0,.05); }
  .mcv-ghf-iconitem h3{ font-size:15px; margin-bottom:6px; color:#191419; }
  .mcv-ghf-iconitem p{ font-size:13px; color:#6d666d; margin:0; }
  .mcv-ghf-icondot{ width:34px; height:34px; border-radius:10px; background:rgba(232,52,79,.12); border:1px solid rgba(232,52,79,.3); flex:none; display:flex; align-items:center; justify-content:center; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:14px; color:#a70d2a; }
  .mcv-ghf-steprow{ display:flex; gap:24px; padding:22px 0; border-bottom:1px solid rgba(11,11,16,0.1); }
  .mcv-ghf-steprow:last-child{ border-bottom:none; }
  .mcv-ghf-step-num{ font-family:'JetBrains Mono',monospace; font-weight:700; font-size:15px; color:#a70d2a; flex:none; width:90px; padding-top:2px; }
  .mcv-ghf-step-body h3{ font-size:17px; color:#191419; margin-bottom:6px; }
  .mcv-ghf-step-body p{ font-size:14.5px; color:#6d666d; margin:0; }
  .mcv-ghf-trustband{ background:#0a0a0a; color:#fff; padding:96px 0; position:relative; overflow:hidden; }
  .mcv-ghf-trustband .ring{ position:absolute; border:1.5px solid rgba(232,52,79,.16); border-radius:50%; width:420px; height:420px; top:-160px; left:-140px; }
  .mcv-ghf-trustband .head{ text-align:center; max-width:720px; margin:0 auto 44px; position:relative; z-index:2; }
  .mcv-ghf-trustband .head .kicker{ font-family:'JetBrains Mono',monospace; font-size:12px; font-weight:700; letter-spacing:.18em; text-transform:uppercase; color:#ff8090; margin-bottom:12px; }
  .mcv-ghf-trustband .head h2{ color:#fff; font-size:clamp(22px,3vw,34px); }
  .mcv-ghf-trustband .head p{ color:rgba(255,255,255,.68); margin-top:14px; }
  /* the band markup uses the prefixed head class, so scope the light colours to it explicitly -
     without this the h2 falls through to .mcv-ghf-head h2 (#191419) and vanishes on the black band */
  .mcv-ghf-trustband .mcv-ghf-head h2{ color:#ffffff; font-size:clamp(22px,3vw,34px); }
  .mcv-ghf-trustband .mcv-ghf-head p{ color:rgba(255,255,255,0.68); }
  .mcv-ghf-trustband .mcv-ghf-head .kicker{ color:#ff8090; }
.mcv-ghf-trustband .mcv-ghf-note{ color:rgba(255,255,255,0.68); }
.mcv-ghf-pt .mcv-ghf-note{ color:rgba(255,255,255,0.68); }
  .mcv-ghf-trustgrid{ display:grid; grid-template-columns:repeat(4,1fr); gap:20px; position:relative; z-index:2; }
  .mcv-ghf-trustcard{ background:rgba(8,3,8,0.82); border:1px solid rgba(255,255,255,0.12); border-radius:16px; padding:26px 22px; }
  .mcv-ghf-trustcard h3{ color:#fff; font-size:15px; margin-bottom:8px; }
  .mcv-ghf-trustcard p{ color:rgba(255,255,255,.68); font-size:13px; margin:0; line-height:1.55; }
  .mcv-ghf-trusticon{ width:38px; height:38px; border-radius:10px; background:rgba(232,52,79,.16); border:1px solid rgba(232,52,79,.4); display:flex; align-items:center; justify-content:center; margin-bottom:14px; }
  .mcv-ghf-scorecard{ background:rgba(8,3,8,0.82); border:1px solid rgba(255,255,255,0.12); border-radius:20px; padding:28px 26px; }
  .mcv-ghf-scorecard .k{ font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:#ff8090; margin-bottom:16px; }
  .mcv-ghf-scorerow{ display:flex; justify-content:space-between; align-items:center; padding:10px 0; border-bottom:1px solid rgba(255,255,255,0.12); }
  .mcv-ghf-scorerow:last-child{ border-bottom:none; }
  .mcv-ghf-scorerow .lbl2{ font-size:12.5px; color:rgba(255,255,255,.75); }
  .mcv-ghf-scorerow .val{ font-family:'JetBrains Mono',monospace; font-size:13px; font-weight:700; color:#fff; }
  .mcv-ghf-scorerow .val.good{ color:#ff8090; }
  /* scorecard is a DARK card sitting in a light section. Rows authored as
     **label**text inherit var(--ink) and vanish (1.13:1).
     Give them light ink and stack them; .lbl2/.val two-column rows are untouched. */
  .mcv-ghf-scorerow{ flex-wrap:wrap; }
  .mcv-ghf-scorecard > .mcv-ghf-scorerow > strong{ flex:1 0 100%; color:#ffffff; font-size:14.5px; margin-bottom:4px; }
  .mcv-ghf-scorecard > .mcv-ghf-scorerow > span{ flex:1 0 100%; color:rgba(255,255,255,0.78); font-size:13px; line-height:1.62; }
  .mcv-ghf-cs-top{ display:flex; justify-content:space-between; align-items:flex-start; gap:24px; flex-wrap:wrap; margin-bottom:28px; }
  .mcv-ghf-cs-top p{ color:#6d666d; font-size:14.5px; max-width:480px; margin:0; }
  .mcv-ghf-cs-meta{ text-align:right; font-size:13.5px; }
  .mcv-ghf-cs-meta strong{ display:block; color:#191419; font-size:14.5px; }
  .mcv-ghf-cs-meta .lbl{ font-family:'JetBrains Mono',monospace; font-size:10.5px; text-transform:uppercase; letter-spacing:.08em; color:#6d666d; margin:2px 0 12px; }
  .mcv-ghf-cs-stats{ display:grid; grid-template-columns:repeat(3,1fr); border:1px solid rgba(11,11,16,0.1); border-radius:16px; margin-bottom:24px; overflow:hidden; }
  .mcv-ghf-cs-stat{ text-align:center; padding:22px 12px; border-right:1px solid rgba(11,11,16,0.1); }
  .mcv-ghf-cs-stat:last-child{ border-right:none; }
  .mcv-ghf-cs-stat .v{ font-family:'JetBrains Mono',monospace; font-weight:700; font-size:26px; color:#a70d2a; }
  .mcv-ghf-cs-stat .l{ font-size:12.5px; color:#6d666d; margin-top:4px; }
  .mcv-ghf-cs-grid{ display:grid; grid-template-columns:1fr 1fr; gap:16px; margin-bottom:16px; }
  .mcv-ghf-cs-box{ background:#faf8f8; border-radius:14px; padding:22px 24px; }
  .mcv-ghf-cs-box .h{ font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:#6d666d; margin-bottom:12px; }
  .mcv-ghf-cs-box ul{ margin:0; padding:0; list-style:none; display:grid; gap:8px; }
  .mcv-ghf-cs-box li{ padding-left:16px; position:relative; font-size:13.5px; color:#191419; line-height:1.55; }
  .mcv-ghf-cs-box li::before{ content:''; position:absolute; left:0; top:7px; width:6px; height:6px; background:#e8344f; transform:rotate(45deg); }
  .mcv-ghf-cs-quote{ border-left:3px solid #e8344f; background:#faf8f8; border-radius:0 14px 14px 0; padding:22px 26px; margin-top:16px; display:flex; gap:16px; align-items:flex-start; }
  .mcv-ghf-cs-quote p{ font-style:italic; font-size:15px; color:#191419; margin:0 0 10px; }
  .mcv-ghf-cs-avatar{ width:38px; height:38px; border-radius:50%; background:#a70d2a; color:#fff; display:flex; align-items:center; justify-content:center; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:13px; flex:none; }
  .mcv-ghf-cs-who strong{ display:block; font-size:13.5px; color:#191419; }
  .mcv-ghf-cs-who span{ font-size:12.5px; color:#6d666d; }
  .mcv-ghf-cs-foot{ margin-top:20px; padding-top:16px; border-top:1px solid rgba(11,11,16,0.1); font-size:12.5px; color:#6d666d; }
  .mcv-ghf-mockwrap{ position:relative; }
  .mcv-ghf-chartcard{ background:rgba(8,3,8,0.82); border:1px solid rgba(255,255,255,0.12); border-radius:20px; padding:28px 26px; position:relative; }
  .mcv-ghf-chartcard .k{ font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:#ff8090; margin-bottom:18px; }
  .mcv-ghf-chartcard .mcv-ghf-barrow{ display:flex; align-items:center; gap:14px; height:auto; margin:0 0 14px; }
  .mcv-ghf-chartcard .mcv-ghf-barrow .l{ flex:0 0 140px; font-size:12.5px; line-height:1.35; color:rgba(255,255,255,.78); }
  .mcv-ghf-chartcard .mcv-ghf-barrow>.bar{ flex:1; height:8px; border-radius:999px; background:rgba(255,255,255,.10); overflow:hidden; }
  .mcv-ghf-chartcard .mcv-ghf-barrow>.bar>.mcv-ghf-barcol{ height:8px; border-radius:999px; background:linear-gradient(90deg,#ff8090,#d81b46); }
  .mcv-ghf-chartcard .note{ margin-top:18px; padding-top:14px; border-top:1px solid rgba(255,255,255,0.12); font-size:11.5px; line-height:1.5; color:rgba(255,255,255,.62); }
  .mcv-ghf-seggrid{ display:grid; grid-template-columns:repeat(4,1fr); gap:20px; }
  .mcv-ghf-segcard{ background:#fff; border:1px solid rgba(11,11,16,0.1); border-radius:16px; padding:26px 22px; box-shadow:0 6px 18px rgba(0,0,0,.05); transition:transform .3s cubic-bezier(.2,.8,.2,1), box-shadow .3s, border-color .3s; }
  .mcv-ghf-segcard:hover{ transform:translateY(-6px); box-shadow:0 20px 40px rgba(0,0,0,.09); border-color:#e8344f; }
  .mcv-ghf-segcard h3{ color:#191419; font-size:15.5px; margin-bottom:8px; }
  .mcv-ghf-segcard p{ color:#6d666d; font-size:13px; margin:0; line-height:1.55; }
  .mcv-ghf-segcard ul{ margin:12px 0 0; padding-left:17px; }
  .mcv-ghf-segcard li{ color:#6d666d; font-size:12.5px; line-height:1.5; margin-bottom:6px; }
  .mcv-ghf-segcard li:last-child{ margin-bottom:0; }
  .mcv-ghf-segicon{ width:38px; height:38px; border-radius:10px; background:rgba(232,52,79,.12); border:1px solid rgba(232,52,79,.3); display:flex; align-items:center; justify-content:center; margin-bottom:14px; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:14px; color:#a70d2a; transition:background .3s; }
  .mcv-ghf-modelgrid{ display:grid; grid-template-columns:repeat(3,1fr); gap:22px; }
  .mcv-ghf-modelcard{ position:relative; background:#fff; border:1px solid rgba(11,11,16,0.1); border-radius:18px; padding:26px 24px; box-shadow:0 6px 18px rgba(0,0,0,.05); transition:transform .3s cubic-bezier(.2,.8,.2,1), box-shadow .3s, border-color .3s; overflow:hidden; }
  .mcv-ghf-modelcard:hover{ transform:translateY(-6px); box-shadow:0 20px 40px rgba(0,0,0,.09); border-color:#e8344f; }
  .mcv-ghf-modelcard .ghost{ position:absolute; top:-4px; right:6px; font-family:'JetBrains Mono',monospace; font-weight:700; font-size:64px; color:#000; opacity:.045; line-height:1; }
  .mcv-ghf-modelcard:hover .ghost{ color:#e8344f; opacity:.09; }
  .mcv-ghf-modelcard .stage{ font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:#a70d2a; margin-bottom:10px; position:relative; }
  .mcv-ghf-modelcard h3{ font-size:16.5px; margin-bottom:8px; position:relative; color:#191419; }
  .mcv-ghf-modelcard p{ font-size:13.5px; color:#6d666d; margin:0; line-height:1.55; position:relative; }
  .mcv-ghf-streamlist{ display:flex; flex-direction:column; gap:9px; }
  .mcv-ghf-streamrow{ display:flex; align-items:center; gap:12px; padding:9px 12px; border:1px solid rgba(255,255,255,0.12); border-radius:10px; background:rgba(255,255,255,.03); }
  .mcv-ghf-streamrow .n{ font-family:'JetBrains Mono',monospace; font-size:11px; font-weight:700; color:#ff8090; }
  .mcv-ghf-streamrow .s{ font-size:13px; color:#fff; font-weight:600; }
  @media (max-width:900px){
    .mcv-ghf-aside ul{ grid-template-columns:1fr; }
    .mcv-ghf-flowrow{ grid-template-columns:48px 1fr; gap:16px; }
    .mcv-ghf-flownum{ width:44px; height:44px; font-size:14px; }
    .mcv-ghf-icongrid,.mcv-ghf-cs-grid,.mcv-ghf-modelgrid{ grid-template-columns:1fr; }
    .mcv-ghf-trustgrid,.mcv-ghf-seggrid{ grid-template-columns:1fr 1fr; }
    .mcv-ghf-cs-stats{ grid-template-columns:1fr; }
    .mcv-ghf-cs-stat{ border-right:none; border-bottom:1px solid rgba(11,11,16,0.1); }
    .mcv-ghf-cs-stat:last-child{ border-bottom:none; }
    .mcv-ghf-cs-top,.mcv-ghf-steprow{ flex-direction:column; }
    .mcv-ghf-cs-meta{ text-align:left; }
    .mcv-ghf-chartcard .mcv-ghf-barrow{ gap:10px; }
    .mcv-ghf-chartcard .mcv-ghf-barrow .l{ flex:0 0 104px; font-size:11.5px; }
  }
* + .mcv-ghf-callout{ margin-top:22px; }
.mcv-ghf-cta .mcv-ghf-byline,.mcv-ghf-cta .mcv-ghf-footerbar{ color:#ffffff; }
.mcv-ghf-cta .mcv-ghf-byline .dotsep{ opacity:.65; }
.mcv-ghf-trustband .kicker,.mcv-ghf-pt .kicker{ color:var(--crimson-light); }
.mcv-ghf-cta .kicker{ color:#ffffff; }
.mcv-ghf-cta .mcv-ghf-footermeta{ color:#ffffff; }
@media (max-width:560px){ .mcv-ghf-trustgrid,.mcv-ghf-seggrid{ grid-template-columns:1fr; } }

  .mcv-ghf-trustgrid{ grid-template-columns:repeat(3,1fr); }
  @media (max-width:900px){ .mcv-ghf-trustgrid{ grid-template-columns:1fr 1fr; } }
  @media (max-width:560px){ .mcv-ghf-trustgrid{ grid-template-columns:1fr; } }

    
    
      
        
          
            [Home](/)/[Grubhub Clone](/grubhub-clone/)/Features
          
          Grubhub Clone · Features
          
# Grubhub Clone Features: Judge It on the Delivery App

          
Demand arrives in two narrow windows a day, and the surface that comes under pressure is dispatch rather than the menu. So the part worth inspecting is the delivery partner application: 234 Dart files across 17 modules, in source, covering assignment, acceptance, navigation, proof of delivery, earnings and the cash being carried. Everything else on this page follows from taking that seriously.

          [Request a Live Demo →](https://miracuves.com/schedule-consultation/)[Full Overview](/grubhub-clone/)
          
            **234** files in the rider app
            **Named** timestamp per transition
            **6 days** to deploy
          
        
        
          Where is my orderA column, not a guess
          
            What an Order Records About Itself
            
              01Placed, and paid for
              02Accepted by the restaurant
              03Prepared and marked ready
              04Assigned to a partner
              05Picked up, then on the way
              06Delivered, with proof
            
          
        
      
    
  

  
    
      
        234Rider App Source Files
        17Rider Feature Modules
        764Admin Routes
        5Clients, One API
      
    
  

  
    
      
        By Role
        
## Feature Set by Role

        
Five surfaces over one Laravel backend, arranged around the handover rather than around the checkout.

      
      
        
          01
          
### The Delivery Partner

          
A real application rather than a wrapper: assignment and acceptance, navigation to pickup and drop-off, proof of delivery at the door, daily and weekly earnings, incentives, and the cash they are currently carrying against their limit. Partners are filtered by zone before assignment, so the work offered is work they can actually reach.

        
        
          02
          
### The Customer

          
They order, then follow it through every state it passes: accepted, being prepared, picked up, on the way, delivered. A map shows where the rider actually is, and in-order chat reaches the restaurant and the partner on the same record, which removes most of the support calls a delivery platform would otherwise take.

        
        
          03
          
### The Restaurant

          
The other side of the handover. Orders arrive, are accepted and prepared, tickets print for the kitchen, and the order is marked ready for collection. The store sees exactly when a rider was assigned and when they arrived, which is what stops the handover becoming an argument nobody can settle.

        
        
          04
          
### The Dispatcher

          
Watch assignment across every zone, step into a live order and reassign a partner, and see the queue building before it becomes a problem. Coverage is drawn on a map with its own charges and rules, so what a dispatcher can do is bounded by geometry rather than by convention.

        
        
          05
          
### The Fleet Manager

          
Approve partners and check documents, set cash ceilings per partner and per store, reconcile collected cash against what was expected, and read performance from the timestamps the orders already carry rather than from a report somebody assembles by hand.

        
        
          06
          
### The Finance Desk

          
Scheduled disbursement settling restaurants and riders from the same run, computed from what was actually charged, with statements, exports and overlap locks so a slow run never pays twice. Sales, commission, delivery, payout and tax reports each show what was charged at the time.

        
      
      
Console roles are scoped so dispatch reaches live orders, support reaches customers, finance reaches payouts, and nobody reaches everything by default. A rider sees the orders assigned to them rather than the whole board.

    
  

  
    
      
        Compare
        
## Clone vs Generic Script vs a Rider App Wrapper

        
Most routes to a delivery marketplace hold up until the first evening rush.

      
      
        
| What decides it | Miracuves Grubhub Clone | A wrapped web view for riders |
| --- | --- | --- |
| What the rider actually uses | 234 files across 17 modules, in source | A page in a shell, with no release path |
| How partners are chosen | Filtered by zone before assignment | Scanned globally, and slower as you grow |
| Answering "where is my order" | A named column per transition | One status field that overwrites itself |
| Cycle time and lateness | A query over data you already have | An analytics project, six months later |
| Cash a partner is carrying | A ceiling, enforced, and reconciled | Whatever they say at the end of the shift |
| A disputed delivery | Proof captured at the door | A tap somebody made in the street |
| Opening a second city | A zone, its charges, an afternoon | Another deployment to keep in step |
| Source code | Yours outright, no per-order royalty | Often limited, sometimes encrypted |

      
      
Grubhub itself is the reference for what this category looks like; it is not a product you can buy or self-host. The commercially useful comparison is the second column against the third, and against a custom build, which is covered on the [Development Cost](/grubhub-clone/development-cost/) page.

    
  

  
    
      
        End to End
        
## How an Order Moves, End to End

        
Seven stages, each one writing its own column on the order rather than overwriting the last.

      
      
        Step 1
### Coverage decides what is orderable

Delivery areas are drawn as polygons with their own charges and rules, so a customer outside the map cannot order into it and produce a run that loses money. Store visibility is scoped to the ordering zone before anything is searched or sorted.

        Step 2
### The order is placed and paid

Search by dish or cuisine, filters, a home feed you control, scheduled orders and standing weekly repeats, then thirteen gateways alongside wallet, cash with a ceiling, and operator-defined offline methods. Split tender is recorded as separate payment legs rather than one blended total.

        Step 3
### The restaurant accepts and prepares

The order lands on the board, a ticket prints for the kitchen, and it is marked ready for collection. Each of those transitions writes its own named timestamp, which is what makes time-to-accept and time-to-ready measurable instead of anecdotal.

        Step 4
### A partner is found within the zone

Delivery partners are filtered by zone before assignment rather than scanned globally, which is what keeps dispatch cost bounded as the fleet grows. Assignment alerts run on zone-scoped push topics, because a partner who sees an offer a minute late is a delivery that is a minute late.

        Step 5
### The handover is recorded

The store sees when a rider was assigned and when they arrived; the rider navigates to pickup and confirms collection. Both sides are looking at the same record, which is what turns a disputed handover from an argument into a timestamp somebody can read.

        Step 6
### It is delivered, with evidence

Navigation to the drop-off, in-order chat if something goes wrong, and proof of delivery captured at the door rather than asserted afterwards. Where cash was collected, it is counted against the ceiling that partner is working under.

        Step 7
### The run settles and reports itself

One scheduled disbursement pays restaurants and riders from what was actually charged, with overlap locks so a slow execution never pays twice. Cycle time, lateness and orders per partner hour are queries over the columns the order already wrote.

      
      
Notification fan-out, disbursement and export pipelines all run off the request path with a scheduler behind them, so the things that must not block a live order do not.

    
  

  
    
      
        Justified
        
## Every Feature Earns Its Place

        
Each row is here because a dispatch operation stops working without it, not because a competitor lists it.

      
      
        
| Module | Why it is in the base build |
| --- | --- |
| A real delivery partner app | A delivery platform competes for riders as hard as it competes for customers, and the application they use all day is most of what they are judging you on. A wrapped web view is a churn problem with a release problem attached. |
| Zone-filtered assignment | Scanning every partner to find one nearby is a cost you pay on every order, growing with your fleet. Filtering by zone first is what keeps dispatch affordable at the exact moment you succeed at recruiting. |
| A named column per transition | A single status field that overwrites itself can answer where an order is now and nothing else. Named timestamps make cycle time, lateness and SLA reporting queries over data you already hold rather than a project. |
| Zone-scoped push topics | Push latency is delivery latency. Sending an assignment alert to one city's topic rather than fanning out across the estate is the difference between a partner responding now and responding after somebody else declined. |
| Cash ceilings and reconciliation | A rider carrying too much float is a risk you cannot see until it goes wrong. Limits enforced per partner and per store, with collected cash checked against what was expected, keep the number visible while it is still small. |
| Proof of delivery | Completion captured at the door rather than asserted afterwards is what makes a disputed delivery a record rather than two accounts. It also protects the partner, which matters when you are trying to keep them. |
| Scoped location data | A rider sees the orders assigned to them rather than the whole board, and a customer sees their own delivery rather than a fleet. Location is the most sensitive data a delivery platform holds and it is scoped accordingly. |
| One run for both sides | Restaurants and riders settling from the same scheduled disbursement, with overlap locks, is what stops the two halves of your payout obligation drifting into two different spreadsheets. |

      
      
A built-in till captures counter and phone orders in the same pipeline, and dine-in runs the same order with the rider steps skipped, so trade that never needed a delivery still lands in the same books.

    
  

  
    
      
        Stack
        
## The Technology Behind the Features

        
Chosen so that the surface which saturates first is the one with the most headroom.

      
      
        **The delivery partner application**234 Dart files across 17 feature modules on Flutter and GetX, shipped as source with its own permissions and release path, covering assignment, acceptance, navigation, proof of delivery, earnings, incentives and cash carried. It is a separate application rather than a mode inside the customer app.
        **Dispatch and geometry**Coverage resolved from zone polygons rather than scans, store visibility scoped to the ordering zone, and partners filtered by zone before any search runs, with per-zone delivery pricing and cash ceilings. Assignment cost tracks the area rather than the size of the fleet.
        **Application core**Laravel 12 on PHP 8.2 and above with MySQL and Passport, holding roughly 300 tables under 378 migrations in strict date order and 136 Eloquent models across eleven domains, with every order transition written as its own named column on the order itself rather than into an event log nobody queries.
        **Surfaces and routing**326 route definitions on API v1, 764 admin console routes behind role and module gates, 258 store panel routes under plan entitlements, and 33 server-rendered storefront pages, each surface behind its own middleware so customer, store and delivery credentials never cross.
        **Realtime and messaging**Firebase Cloud Messaging on HTTP v1 with per-project service-account authentication and zone-scoped topics so an assignment alert reaches one city, a Pusher-compatible websocket server with Laravel Echo, and in-order chat between customer, store and delivery partner on the same record.
        **Money and queues**Thirteen gateways plus wallet, cash and offline rails, commission and discount split frozen at settlement, one disbursement run settling restaurants and riders with overlap locks, and notification fan-out, payouts and exports all running off the request path with a scheduler behind them.
      
      
One Laravel monolith owns every business rule and the five surfaces sit over one versioned API, so a reassignment made in the console is true in the rider app, the store panel and the customer's tracking view within the same request.

    
  

  
    
    
      
        Honest Readiness
        
## What Is Not Included in the Base Package

        
A fixed price only means something if the boundary around it is stated, so this is that boundary.

      
      
        
          01
          
### Assignment is single-order

          
Dispatch is zone-scoped and assigns one order at a time. Grouping several orders onto one run, and optimizing the sequence of stops within it, is genuine work rather than a setting. It is worth scoping once your density makes batching worthwhile, and not before.

        
        
          02
          
### No corporate or campus accounts

          
Ordering on behalf of an organization, with departmental budgets, approval chains and invoiced billing rather than per-order payment, is a different commercial model and it is not built. If office catering or campus meal plans are central to your plan, raise it on the first call.

        
        
          03
          
### Riders are yours, or an integration

          
The delivery partner app assumes you run your own fleet, which is the right assumption for an operator whose whole argument is dispatch quality. Connecting a third-party courier for the areas where you would rather not is scoped separately and depends on the API that company publishes.

        
        
          04
          
### The platform ships in test mode

          
One-time passcodes are exposed for testing, cross-origin rules are permissive and transport and frame headers are not emitted, all named in the documentation rather than found later. Closing them is a pre-launch hardening pass quoted separately, and no second factor sits in front of dispatcher sign-in.

        
        
          05
          
### Three things are scoped separately

          
Signing and releasing the iOS builds including the delivery app, bringing console access under your identity provider with a second factor for dispatchers, and pushing order, cycle-time and payout rows into an analytics stack your team already runs. Each is quoted before it starts.

        
        
          06
          
### What is built is real

          
A 234 file delivery application in source, zone-filtered assignment, a named column per transition, zone-scoped push topics, enforced cash ceilings with reconciliation, proof of delivery, scoped location data, one disbursement run for both sides with overlap locks, and a security posture published against OWASP categories.

        
      
      
What no codebase supplies is riders and restaurants. A delivery platform competes for partners as hard as for customers, and recruiting them is field work rather than software, which is why it is stated here rather than implied away.

    
  

  
    
      
        
          Development Company
          
### See how Miracuves compares to agencies and freelancers

          
The deployment process, the nine questions worth asking anyone bidding on a dispatch build, the red flags, and the Flyereats engagement we delivered in 2025 - on the Development Company page.

        
        [See the comparison →](/grubhub-clone/development-company/)
      
    
  

  
    
      
        FAQ
        
## Frequently Asked Questions

      
      
        
          
            What does the delivery partner app actually do?
            It is a full application at 234 Dart files across 17 feature modules, shipped as source with its own permissions and its own release path rather than as a mode inside the customer app. A partner accepts or declines an assignment, navigates to the pickup, confirms collection, navigates to the drop-off, captures proof of delivery, and sees their earnings, their incentives and the cash they are currently carrying against the ceiling you set. That application is what your riders judge you on every day.
          
          
            How does assignment work?
            Partners are filtered by zone before assignment rather than scanned globally. That is a performance decision and a cost decision at the same time: the work of finding somebody nearby tracks the size of the area rather than the size of your fleet, which matters because dispatch is the surface that saturates first at peak. Alerts go out on zone-scoped push topics, because a partner who sees an offer a minute late produces a delivery that is a minute late.
          
          
            Can I measure cycle time and lateness?
            From day one, and without an analytics project, because the measurement ships with the data. Every transition an order passes through writes its own named column rather than overwriting a single status field. Time-to-accept, time-to-ready, time-to-assign, time-to-pickup and time-to-door are therefore queries over rows you already have. Where transitions overwrite one another, those numbers do not exist and cannot be reconstructed afterwards.
          
        
        
          
            How is cash handled?
            As a number you can see rather than a number you hear about later. Ceilings are enforced per delivery partner and per store rather than advised, so a partner over their limit stops being assigned cash orders until they settle. Collected cash is then reconciled against what was expected, which is what keeps exposure visible while it is still small. The remaining cost is operational, being physical collection and banking, and that belongs in your plan rather than in ours.
          
          
            Does the platform support batched deliveries?
            Not in the base build, and this is worth being clear about because it is the question most likely to matter to a dense operation. Assignment is zone-scoped and single-order by default. Grouping several orders onto one run, and optimizing the sequence of stops within it, is genuine engineering rather than a setting, and we scope it separately. It is also work that only pays back above a density most operators do not have in their first year.
          
          
            Can the same fleet carry things other than restaurant food?
            Yes, and for a dispatch-led operator this is often the strongest argument for the model. Groceries, pharmacy lines and courier parcels run through the same catalogue machinery, the same riders and the same assignment surface, which means you are spreading the cost of a fleet you have already recruited across more than one demand curve. Restaurant peaks are narrow; parcels and groceries fill the hours between them.
          
        
      
    
  

  
    
    
      
        
## Open the rider app before anything else

On the demo, take an assignment as a delivery partner, deliver it with proof, then read the timestamps that order wrote about itself in the console.

        [Request a Live Demo](https://miracuves.com/schedule-consultation/)[Full Overview](/grubhub-clone/)
      
    
  

  
    
      
        Explore
        
## Explore the Grubhub Clone

      
      
        [Overview](/grubhub-clone/)
        [Features](/grubhub-clone/features/)
        [Development Cost](/grubhub-clone/development-cost/)
        [Development Company](/grubhub-clone/development-company/)
        [Business Model](/grubhub-clone/business-model/)
      
    
  

  
    
    
      
        
## Cost per delivery is the metric. All three inputs are yours.

        
Assignment quality, zone density and orders per partner hour decide whether a delivery marketplace works, and every one of them is something you control inside a platform you own outright.

        [Talk to Us →](https://miracuves.com/schedule-consultation/)
      
      
        
          **Written by the Miracuves Product Team**·
          Reviewed for accuracy·
          Last updated **September 10, 2026**
        
        
          Miracuves · Grubhub Clone Solution
          Feature set, stack and stated limitations cross-verified against the hub, 2026-09-10
        
      
    
  

				
				
				
				
						
					
			
						
				
					
  /* MIRACUVES - TRADEMARK / NON-AFFILIATION NOTICE (v3).
     Scoped under .mcv-tmn so it cannot collide with the hub connector (mcv-hubx-, mcv-hubxa-)
     or any block above it. Always the last block on the page, immediately before the footer.
     Structure is deliberate: one plain-language lead people actually read, then the three
     supporting positions split out so each is scannable rather than buried in a paragraph.
     Fonts are declared but not loaded: pages carrying the connector already have them, and the
     fallbacks are deliberate so this block never adds a render-blocking request. */
  .mcv-tmn{ font-family:'Plus Jakarta Sans',Arial,sans-serif; color:#191419; margin:0; padding:0; }
  .mcv-tmn *{ box-sizing:border-box; }
  .mcv-tmn-band{ background:#ffffff; padding:8px 0 76px; }
  .mcv-tmn-wrap{ max-width:1180px; margin:0 auto; padding:0 24px; }
  .mcv-tmn-box{ background:#faf8f8; border:1px solid rgba(11,11,16,0.13); border-left:4px solid #a70d2a; border-radius:12px; padding:34px 38px; box-shadow:0 1px 2px rgba(25,20,25,0.04), 0 10px 30px rgba(25,20,25,0.05); }
  .mcv-tmn-head{ display:flex; align-items:center; gap:11px; margin:0 0 18px; }
  .mcv-tmn-dot{ width:8px; height:8px; background:#a70d2a; transform:rotate(45deg); flex:0 0 auto; }
  .mcv-tmn .mcv-tmn-head span.mcv-tmn-kicker{ font-family:'JetBrains Mono',ui-monospace,monospace; font-size:13px; font-weight:700; letter-spacing:.2em; text-transform:uppercase; color:#a70d2a; }
  .mcv-tmn .mcv-tmn-box p.mcv-tmn-lead{ margin:0 0 24px; font-size:20px; line-height:1.5; font-weight:600; color:#191419; max-width:56ch; letter-spacing:-.01em; }
  .mcv-tmn .mcv-tmn-box b.mcv-tmn-brand{ color:#a70d2a; font-weight:700; }
  .mcv-tmn-cols{ display:grid; grid-template-columns:repeat(3,1fr); gap:26px 36px; padding-top:24px; border-top:1px solid rgba(11,11,16,0.11); }
  .mcv-tmn .mcv-tmn-col span.mcv-tmn-lbl{ display:block; font-family:'JetBrains Mono',ui-monospace,monospace; font-size:10.5px; font-weight:700; letter-spacing:.14em; text-transform:uppercase; color:#8a8085; margin:0 0 8px; }
  .mcv-tmn .mcv-tmn-col p{ margin:0; font-size:14px; line-height:1.7; color:#453d42; }
  .mcv-tmn-foot{ margin-top:26px; padding-top:18px; border-top:1px solid rgba(11,11,16,0.11); }
  .mcv-tmn .mcv-tmn-foot a{ font-family:'JetBrains Mono',ui-monospace,monospace; font-size:12px; font-weight:600; letter-spacing:.04em; color:#a70d2a; text-decoration:none; border-bottom:1px solid rgba(167,13,42,0.32); }
  .mcv-tmn .mcv-tmn-foot a:hover{ border-bottom-color:#a70d2a; }
  @media (max-width:900px){
    .mcv-tmn-cols{ grid-template-columns:1fr; gap:22px; }
    .mcv-tmn .mcv-tmn-box p.mcv-tmn-lead{ font-size:18px; }
  }
  @media (max-width:600px){
    .mcv-tmn-band{ padding:4px 0 48px; }
    .mcv-tmn-box{ padding:26px 22px; border-radius:10px; border-left-width:3px; }
    .mcv-tmn .mcv-tmn-box p.mcv-tmn-lead{ font-size:17px; line-height:1.45; margin-bottom:20px; }
    .mcv-tmn .mcv-tmn-head span.mcv-tmn-kicker{ font-size:12px; letter-spacing:.16em; }
  }

  
    
      
        Disclaimer
        
Miracuves is an independent software development company. We are not affiliated with, connected to, sponsored by, or endorsed by **Grubhub**.

        
          
            Why this name
            
“**Grubhub** Clone” is used descriptively. It is how the software industry refers to building a platform with functionality similar to Grubhub, and how clients search for it.

          
          
            Who built this
            
The entire design and codebase is built by our own team. The product contains no code, design, graphics, or content originating from the Grubhub website or applications.

          
          
            Trademarks
            
**Grubhub** and all other third-party names and marks are the property of their respective owners, referenced here solely to describe the category of software offered.

          
        
        [Read our full Legal Notice & Disclaimer →](/disclaimer/)
