1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3879],{3879:function(e,n,a){Promise.resolve().then(a.bind(a,8388))},2739:function(e,n,a){"use strict";a.r(n);var t=a(7437),s=a(7648);n.default=e=>{let{href:n,...a}=e,r=n&&n.startsWith("/"),i=n&&n.startsWith("#");return r?(0,t.jsx)(s.default,{className:"break-words",href:n,...a}):i?(0,t.jsx)("a",{className:"break-words",href:n,...a}):(0,t.jsx)("a",{className:"break-words",target:"_blank",rel:"noopener noreferrer",href:n,...a})}},3825:function(e,n,a){"use strict";var t=a(257);let s={title:"Devity",author:"Abhishek Thakur",headerTitle:"Devity",description:"Devity offers free developer tools, technical blog posts, Chrome extensions, and mobile apps. Build faster with our JSON formatter, UUID generator, Base64 converter, and more.",language:"en-us",theme:"dark",siteUrl:"https://www.devity.in",siteRepo:"https://github.com/devity-in/blog",siteLogo:"".concat(t.env.BASE_PATH||"","/static/images/logo.png"),socialBanner:"".concat(t.env.BASE_PATH||"","/static/images/devity-blog.png"),mastodon:"https://mastodon.social/@mastodonuser",email:"[email protected]",github:"https://github.com/devity-in",x:"https://twitter.com/devity_in",leetcode:"https://leetcode.cn/u/devity-in/",facebook:"https://www.facebook.com/devity-in",youtube:"https://www.youtube.com/@devity-in",linkedin:"https://www.linkedin.com/in/devity-in",threads:"https://www.threads.net/@devity_in",instagram:"https://www.instagram.com/devity_in",locale:"en-US",stickyNav:!0,analytics:{googleAnalytics:{googleAnalyticsId:t.env.NEXT_PUBLIC_GOOGLE_ANALYTICS_ID}},comments:{provider:"giscus",giscusConfig:{repo:"devity-in/blog",repositoryId:"R_kgDOOw3d3A",category:"General",categoryId:"DIC_kwDOOw3d3M4Cqm3e",mapping:"pathname",reactions:"1",metadata:"0",theme:"dark",darkTheme:"transparent_dark",themeURL:"",lang:"en"}},search:{provider:"kbar",kbarConfig:{searchDocumentsPath:"".concat(t.env.BASE_PATH||"","/search.json")}}};e.exports=s},8388:function(e,n,a){"use strict";a.d(n,{default:function(){return y}});var t=a(7437),s=a(3145);let r=a(257).env.BASE_PATH;var i=e=>{let{src:n,...a}=e;return(0,t.jsx)(s.default,{src:"".concat(r||"").concat(n),...a})},o=a(9376),l=a(1235);a(6822);var c=(e,n)=>{let a=Object.assign({},e);return n.forEach(e=>{delete a[e]}),a},d=JSON.parse('[{"title":"Daily Flow â A Minimalist, Day-First Task Management System","date":"2026-04-21T00:00:00.000Z","tags":["Web App","Task Management","Productivity","Day-First","Minimalist","devity-engineering"],"keywords":[],"lastmod":"2026-04-21T00:00:00.000Z","draft":false,"summary":"Daily Flow is a minimalist, day-first task management system that helps you focus on what matters today. Unfinished tasks carry forward automatically, only one task can be \\"In Progress\\" at a time, and your complete history stays visible.","images":"/static/images/dailyflow-screenshot.png","layout":"PostLayout","canonicalUrl":"","faqs":[],"body":{"raw":"\\n# The Spark: The Weight of Seeing Everything at Once\\n\\nEvery time you open a typical task manager, a familiar overwhelm unfolds. Fifty tasks stare back at you. Some from last week, some from last month, some you forgot you added. You scroll, you sort, you filter â and by the time you decide what to work on, the energy to actually do the work is gone.\\n\\nMost task managers are built to capture everything. Theyâre great at storing tasks, but bad at helping you focus on the one thing that matters right now. Old tasks hide, priorities drift, and a âquick check of the listâ becomes a daily ritual of decision fatigue.\\n\\nThen, when you want to pick up where you left off yesterday, you end up manually dragging unfinished tasks into today, rewriting descriptions, and reshuffling priorities. The tool designed to reduce work ends up creating more of it.\\n\\nThatâs where **Daily Flow** comes in.\\n\\n## The Idea: Today First, History Below\\n\\nWhat if a task manager showed you today first â and kept the rest of your history quietly available, but out of the way?\\n\\nWhat if, instead of managing your list, you just worked?\\n\\n- Unfinished tasks carry forward to today automatically â no copying, no dragging.\\n- Only one task can be âIn Progressâ at a time, so you always know what to focus on.\\n- Finished tasks sink to the bottom, keeping active work visible.\\n- Your complete history stays one scroll away, never deleted, never hidden.\\n\\nKnowledge workers, freelancers, and students would no longer spend the first 15 minutes of their day reorganizing a task list. Theyâd open the app, see what theyâre working on, and start.\\n\\nThis is the core vision of **Daily Flow**:\\n\\n> A day-first, minimalist task manager that carries your work forward automatically and keeps you focused on one task at a time.\\n\\n## What Problem Are We Solving?\\n\\n- Decision fatigue from seeing every task youâve ever added on one screen.\\n- Manual migration of unfinished tasks from yesterday to today.\\n- Multitasking disguised as productivity â five âactiveâ tasks, none finished.\\n- Old task history getting hidden or deleted, losing context and learnings.\\n- Complex setup, databases, and accounts just to track a handful of tasks.\\n- Privacy concerns from cloud-first tools that demand your data before theyâll work.\\n\\n## How Daily Flow Solves It\\n\\nâ
**Today-First View**: \\nYou open Daily Flow and see today. Past tasks are there, scrolled below, in chronological order â but today is the headline.\\n\\nâ
**Single Active Task**: \\nOnly one task can be âIn Progressâ at a time. Mark a new one active, and the previous one automatically resets. No more five-things-at-once illusion of progress.\\n\\nâ
**Automatic Carry-Forward**: \\nWhen a new day starts, unfinished tasks move to today automatically. The task that was âIn Progressâ stays âIn Progress.â Other unfinished tasks reset to âNo Statusâ so you can decide what matters today.\\n\\nâ
**Auto-Priority & Smart Sorting**: \\nThe active task automatically gets high priority and moves to the top. Then tasks are ordered by priority (high, medium, low). Finished tasks sink to the bottom. You can still drag to reorder anytime.\\n\\nâ
**Zero Setup, Works Offline**: \\nOpen it and start. No database, no account, no onboarding. Guest mode stores data in your browser; everything works offline.\\n\\nâ
**Optional Google Drive Sync**: \\nSign in with Google if you want to access your tasks across devices. If you start as a guest, your data migrates to Drive automatically when you sign in.\\n\\nâ
**Complete History, Always Visible**: \\nFinished tasks stay in their original dates. Scroll down to see what you accomplished last week, last month, last quarter. Learn from your patterns instead of losing them.\\n\\nâ
**Excel Export**: \\nExport all your tasks to Excel anytime for analysis, reporting, or archival. Your data is yours â JSON file format under the hood, easy to back up or move.\\n\\n## How It Works\\n\\n### Every Day Starts Fresh\\n\\nWhen you open Daily Flow on a new day:\\n\\n- Your âIn Progressâ task from yesterday stays âIn Progressâ â your active work continues seamlessly.\\n- Other unfinished tasks reset to âNo Statusâ so you can decide what to prioritize today.\\n- Finished tasks remain in their original dates for historical reference.\\n\\n### Focus on One Task at a Time\\n\\nThe âIn Progressâ status is deliberately exclusive:\\n\\n- Only one task can be active at a time.\\n- Marking a new task active automatically resets the previously active one.\\n- The active task gets high priority and moves to the top.\\n- You avoid multitasking and stay focused on whatâs in front of you.\\n\\n### Smart Organization\\n\\nTasks sort themselves:\\n\\n- âIn Progressâ at the top.\\n- Then high, medium, low priority.\\n- Finished tasks at the bottom.\\n- Drag to reorder manually anytime.\\n\\n## What Makes It Different\\n\\n**1. Today Comes First** \\nOther task managers show you everything. Daily Flow shows you today first, with history below. One small change â less overwhelm, more focus.\\n\\n**2. Everything Happens Automatically** \\nTasks carry forward. Priorities adjust with status. Sorting just works. You focus on your work, not on managing the tool.\\n\\n**3. Your Data, Your Control** \\nA simple JSON file under the hood. Back it up, move it, edit it directly if you want. No complex databases, no lock-in. Optional Drive sync
1when you need it.\\n\\n**4. Complete History** \\nNothing is hidden or deleted. See what you accomplished, track patterns, reference past work, learn from your own history.\\n\\n**5. Single Focus System** \\nThe âone In Progress taskâ rule feels limiting at first â then liberating. No decision paralysis, no multitasking, always a clear next thing.\\n\\n## Key Features\\n\\n### Smart Task Management\\n\\n- **Single Active Task** â Only one task can be âIn Progressâ at a time.\\n- **Auto-Priority** â Active tasks automatically get high priority.\\n- **Smart Sorting** â Organized by status, then priority, then recency.\\n- **Visual Hierarchy** â Important tasks rise to the top automatically.\\n\\n### Seamless Daily Transitions\\n\\n- **Automatic Carry-Forward** â Unfinished tasks move to today automatically.\\n- **Status Preservation** â âIn Progressâ tasks stay âIn Progress.â\\n- **Fresh Start** â Other unfinished tasks reset for a new day.\\n- **Zero Manual Work** â Everything happens in the background.\\n\\n### Flexible Data Storage\\n\\n- **Guest Mode** â Works immediately with browser storage.\\n- **Cloud Sync** â Optional Google Drive integration.\\n- **Easy Backup** â Simple JSON file you can copy anywhere.\\n- **Portable** â Your data travels with you.\\n\\n### Reporting & Analysis\\n\\n- **Excel Export** â Export all your tasks for analysis.\\n- **Complete History** â Track productivity over time.\\n- **Status Tracking** â See what you completed and when.\\n- **Priority Insights** â Understand your prioritization habits.\\n\\n## The Experience\\n\\n**Simplicity First** â Clean, minimalist interface. No learning curve. Fast and lightweight. Works beautifully on phone, tablet, and desktop.\\n\\n**Powerful Yet Simple** â Drag-and-drop reordering. Click to edit tasks inline. Easy status and priority management. Full text display â nothing gets cut off.\\n\\n## Perfect For\\n\\n- Knowledge workers who want better daily focus.\\n- Freelancers managing multiple projects.\\n- Students organizing coursework and deadlines.\\n- Small teams needing simple task coordination.\\n- Anyone who values simplicity over complexity.\\n\\n## Great For\\n\\n- Daily planning and standups.\\n- Personal productivity tracking.\\n- Small team task management.\\n- Project progress monitoring.\\n- Recurring task workflows.\\n- Long-term goal tracking.\\n\\n## Daily Flow vs Traditional Task Managers\\n\\n| Feature | Daily Flow | Traditional Task Managers |\\n| --------------- | ------------------------- | ------------------------- |\\n| **Focus** | Today-first | Everything at once |\\n| **Setup** | Zero setup | Database required |\\n| **Automation** | Intelligent carry-forward | Manual migration |\\n| **Focus System**| Single active task | Multiple active tasks |\\n| **History** | Complete visibility | Often hidden/deleted |\\n| **Complexity** | Minimalist | Feature-heavy |\\n| **Data Control**| Simple JSON | Complex databases |\\n| **Learning Curve** | Instant | Steep |\\n\\n## Getting Started\\n\\n1. **Open Daily Flow** â no sign-up required for guest mode.\\n2. **Add your first task** â type it in and press Enter.\\n3. **Mark a task âIn Progressâ** â only one at a time, so you stay focused.\\n4. **Watch tasks carry forward** â when a new day starts, unfinished tasks move to today automatically.\\n5. **Sign in with Google (optional)** â sync across devices whenever youâre ready.\\n\\n## Your Data\\n\\n- **Guest Mode** â Your data stays in your browser (localStorage).\\n- **Google Drive Sync** â Sign in to sync across devices.\\n- **Automatic Migration** â Sign in after using guest mode and your data moves to Drive automatically.\\n- **Export** â Export everything to Excel anytime.\\n- **Backup** â A single data file, easy to back up or move.\\n\\n## The Future: Focus on Today, Learn from Yesterday\\n\\nWith **Daily Flow**, you focus on today, keep yesterday as context, and plan tomorrow without drowning in a pile of tasks. No complex setup, no overwhelming interfaces, no manual migration â just pure, day-first productivity.\\n\\nThis is more than a tool.\\n\\n> Itâs where simplicity meets productivity â a task manager that gets out of your way so you can actually do the work.\\n","code":"var Component=(()=>{var g=Object.create;var i=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var p=(t,a)=>()=>
1(a||t((a={exports:{}}).exports,a),a.exports),f=(t,a)=>{for(var r in a)i(t,r,{get:a[r],enumerable:!0})},o=(t,a,r,l)=>{if(a&&typeof a==\\"object\\"||typeof a==\\"function\\")for(let n of y(a))!w.call(t,n)&&n!==r&&i(t,n,{get:()=>a[n],enumerable:!(l=u(a,n))||l.enumerable});return t};var k=(t,a,r)=>(r=t!=null?g(m(t)):{},o(a||!t||!t.__esModule?i(r,\\"default\\",{value:t,enumerable:!0}):r,t)),v=t=>o(i({},\\"__esModule\\",{value:!0}),t);var d=p((M,s)=>{s.exports=_jsx_runtime});var x={};f(x,{default:()=>c,frontmatter:()=>b});var e=k(d()),b={title:\\"Daily Flow \\\\u2014 A Minimalist, Day-First Task Management System\\",date:\\"2026-04-21\\",lastmod:\\"2026-04-21\\",tags:[\\"Web App\\",\\"Task Management\\",\\"Productivity\\",\\"Day-First\\",\\"Minimalist\\",\\"devity-engineering\\"],draft:!1,images:\\"/static/images/dailyflow-screenshot.png\\",summary:\'Daily Flow is a minimalist, day-first task management system that helps you focus on what matters today. Unfinished tasks carry forward automatically, only one task can be \\"In Progress\\" at a time, and your complete history stays visible.\',layout:\\"PostLayout\\",canonicalUrl:\\"\\"};function h(t){let a={a:\\"a\\",blockquote:\\"blockquote\\",br:\\"br\\",h1:\\"h1\\",h2:\\"h2\\",h3:\\"h3\\",li:\\"li\\",ol:\\"ol\\",p:\\"p\\",path:\\"path\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",table:\\"table\\",tbody:\\"tbody\\",td:\\"td\\",th:\\"th\\",thead:\\"thead\\",tr:\\"tr\\",ul:\\"ul\\",...t.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsxs)(a.h1,{className:\\"content-header\\",id:\\"the-spark-the-weight-of-seeing-everything-at-once\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-spark-the-weight-of-seeing-everything-at-once\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Spark: The Weight of Seeing Everything at Once\\"]}),(0,e.jsx)(a.p,{children:\\"Every time you open a typical task manager, a familiar overwhelm unfolds. Fifty tasks stare back at you. Some from last week, some from last month, some you forgot you added. You scroll, you sort, you filter \\\\u2014 and by the time you decide what to work on, the energy to actually do the work is gone.\\"}),(0,e.jsx)(a.p,{children:\\"Most task managers are built to capture everything. They\\\\u2019re great at storing tasks, but bad at helping you focus on the one thing that matters right now. Old tasks hide, priorities drift, and a \\\\u201Cquick check of the list\\\\u201D becomes a daily ritual of decision fatigue.\\"}),(0,e.jsx)(a.p,{children:\\"Then, when you want to pick up where you left off yesterday, you end up manually dragging unfinished tasks into today, rewriting descriptions, and reshuffling priorities. The tool designed to reduce work ends up creating more of it.\\"}),(0,e.jsxs)(a.p,{children:[\\"That\\\\u2019s where \\",(0,e.jsx)(a.strong,{children:\\"Daily Flow\\"}),\\" comes in.\\"]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"the-idea-today-first-history-below\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-idea-today-first-history-below\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Idea: Today First, History Below\\"]}),(0,e.jsx)(a.p,{children:\\"What if a task manager showed you today first \\\\u2014 and kept the rest of your history quietly available, but out of the way?\\"}),(0,e.jsx)(a.p,{children:\\"What if, instead of managing your list, you just worked?\\"}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:\\"Unfinished tasks carry forward to today automatically \\\\u2014 no copying, no dragging.\\"}),(0,e.jsx)(a.li,{children:\\"Only one task can be \\\\u201CIn Progress\\\\u201D at a time, so you always know what to focus on.\\"}),(0,e.jsx)(a.li,{children:\\"Finished tasks sink to the bottom, keeping active work visible.\\"}),(0,e.jsx)(a.li,{children:\\"Your complete history stays one scroll away, never deleted, never hidden.\\"})]}),(0,e.jsx)(a.p,{children:\\"Knowledge workers, freelancers, and students would no longer spend the first 15 minutes of their day reorganizing a task list. They\\\\u2019d open the app, see what they\\\\u2019re working on, and start.\\"}),(0,e.jsxs)(a.p,{children:[\\"This is the core vision of \\",(0,e.jsx)(a.strong,{children:\\"Daily Flow\\"}),\\":\\"]}),(0,e.jsx)(a.blockquote,{children:(0,e.jsx)(a.p,{children:\\"A day-first, minimalist task manager that carries your work forward automatically and keeps you focused on one task at a time.\\"})}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"what-problem-are-we-solving\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#what-problem-are-we-solving\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Problem Are We Solving?\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:\\"Decision fatigue from seeing every task you\\\\u2019ve ever added on one screen.\\"}),(0,e.jsx)(a.li,{children:\\"Manual migration of unfinished tasks from yesterday to today.\\"}),(0,e.jsx)(a.li,{children:\\"Multitasking disguised as productivity \\\\u2014 five \\\\u201Cactive\\\\u201D tasks, none finished.\\"}),(0,e.jsx)(a.li,{children:\\"Old task history getting hidden or deleted, losing context and learnings.\\"}),(0,e.jsx)(a.li,{children:\\"Complex setup, databases, and accounts just to track a handful of tasks.\\"}),(0,e.jsx)(a.li,{children:\\"Privacy concerns from cloud-first tools that demand your data before they\\\\u2019ll work.\\"})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"how-daily-flow-solves-it\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#how-daily-flow-solves-it\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"How Daily Flow Solves It\\"]}),(0,e.jsxs)(a.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(a.strong,{children:\\"Today-First View\\"}),\\":\\",(0,e.jsx)(a.br,{}),\\"You open Daily Flow and see today. Past tasks are there, scrolled below, in chronological order \\\\u2014 but today is the headline.\\"]}),(0,e.jsxs)(a.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(a.strong,{children:\\"Single Active Task\\"}),\\":\\",(0,e.jsx)(a.br,{}),\\"Only one task can be \\\\u201CIn Progress\\\\u201D at a time. Mark a new one active, and the previous one automatically resets. No more five-things-at-once illusion of progress.\\"]}),(0,e.jsxs)(a.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(a.strong,{children:\\"Automatic Carry-Forward\\"}),\\":\\",(0,e.jsx)(a.br,{}),\\"When a new day starts, unfinished tasks move to today automatically. The task that was \\\\u201CIn Progress\\\\u201D stays \\\\u201CIn Progress.\\\\u201D Other unfinished tasks reset to \\\\u201CNo Status\\\\u201D so you can decide what matters today.\\"]}),(0,e.jsxs)(a.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(a.strong,{children:\\"Auto-Priority & Smart Sorting\\"}),\\":\\",(0,e.jsx)(a.br,{}),\\"The active task automatically gets high priority and moves to the top. Then tasks are ordered by priority (high, medium, low). Finished tasks sink to the bottom. You can still drag to reorder anytime.\\"]}),(0,e.jsxs)(a.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(a.strong,{children:\\"Zero Setup, Works Offline\\"}),\\":\\",(0,e.jsx)(a.br,{}),\\"Open it and start. No database, no account, no onboarding. Guest mode stores data in your browser; everything works offline.\\"]}),(0,e.jsxs)(a.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(a.strong,{children:\\"Optional Google Drive Sync\\"}),\\":\\",(0,e.jsx)(a.br,{}),\\"Sign in with Google if you want to access your tasks across devices. If you start as a guest, your data migrates to Drive automatically when you sign in.\\"]}),(0,e.jsxs)(a.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(a.strong,{children:\\"Complete History, Always Visible\\"}),\\":\\",(0,e.jsx)(a.br,{}),\\"Finished tasks stay in their original dates. Scroll down to see what you accomplished last week, last month, last quarter. Learn from your patterns instead of losing them.\\"]}),(0,e.jsxs)(a.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(a.strong,{children:\\"Excel Export\\"}),\\":\\",(0,e.jsx)(a.br,{}),\\"Export all your tasks to Excel anytime for analysis, reporting, or archival. Your data is yours \\\\u2014 JSON file format under the hood, easy to back up or move.\\"]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"how-it-works\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#how-it-works\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"How It Works\\"]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"every-day-starts-fresh\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#every-day-starts-fresh\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Every Day Starts Fresh\\"]}),(0,e.jsx)(a.p,{children:\\"When you open Daily Flow on a new day:\\"}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:\\"Your \\\\u201CIn Progress\\\\u201D task from yesterday stays \\\\u201CIn Progress\\\\u201D \\\\u2014 your active work continues seamlessly.\\"}),(0,e.jsx)(a.li,{children:\\"Other unfinished tasks reset to \\\\u201CNo Status\\\\u201D so you can decide what to prioritize today.\\"}),(0,e.jsx)(a.li,{children:\\"Finished tasks remain in their original dates for historical reference.\\"})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"focus-on-one-task-at-a-time\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#focu
1s-on-one-task-at-a-time\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Focus on One Task at a Time\\"]}),(0,e.jsx)(a.p,{children:\\"The \\\\u201CIn Progress\\\\u201D status is deliberately exclusive:\\"}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:\\"Only one task can be active at a time.\\"}),(0,e.jsx)(a.li,{children:\\"Marking a new task active automatically resets the previously active one.\\"}),(0,e.jsx)(a.li,{children:\\"The active task gets high priority and moves to the top.\\"}),(0,e.jsx)(a.li,{children:\\"You avoid multitasking and stay focused on what\\\\u2019s in front of you.\\"})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"smart-organization\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#smart-organization\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Smart Organization\\"]}),(0,e.jsx)(a.p,{children:\\"Tasks sort themselves:\\"}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:\\"\\\\u201CIn Progress\\\\u201D at the top.\\"}),(0,e.jsx)(a.li,{children:\\"Then high, medium, low priority.\\"}),(0,e.jsx)(a.li,{children:\\"Finished tasks at the bottom.\\"}),(0,e.jsx)(a.li,{children:\\"Drag to reorder manually anytime.\\"})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"what-makes-it-different\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#what-makes-it-different\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Makes It Different\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"1. Today Comes First\\"}),(0,e.jsx)(a.br,{}),\\"Other task managers show you everything. Daily Flow shows you today first, with history below. One small change \\\\u2014 less overwhelm, more focus.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"2. Everything Happens Automatically\\"}),(0,e.jsx)(a.br,{}),\\"Tasks carry forward. Priorities adjust with status. Sorting just works. You focus on your work, not on managing the tool.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"3. Your Data, Your Control\\"}),(0,e.jsx)(a.br,{}),\\"A simple JSON file under the hood. Back it up, move it, edit it directly if you want. No complex databases, no lock-in. Optional Drive sync
1when you need it.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"4. Complete History\\"}),(0,e.jsx)(a.br,{}),\\"Nothing is hidden or deleted. See what you accomplished, track patterns, reference past work, learn from your own history.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"5. Single Focus System\\"}),(0,e.jsx)(a.br,{}),\\"The \\\\u201Cone In Progress task\\\\u201D rule feels limiting at first \\\\u2014 then liberating. No decision paralysis, no multitasking, always a clear next thing.\\"]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"key-features\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#key-features\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Key Features\\"]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"smart-task-management\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#smart-task-management\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Smart Task Management\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Single Active Task\\"}),\\" \\\\u2014 Only one task can be \\\\u201CIn Progress\\\\u201D at a time.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Auto-Priority\\"}),\\" \\\\u2014 Active tasks automatically get high priority.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Smart Sorting\\"}),\\" \\\\u2014 Organized by status, then priority, then recency.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Visual Hierarchy\\"}),\\" \\\\u2014 Important tasks rise to the top automatically.\\"]})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"seamless-daily-transitions\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#seamless-daily-transitions\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Seamless Daily Transitions\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Automatic Carry-Forward\\"}),\\" \\\\u2014 Unfinished tasks move to today automatically.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Status Preservation\\"}),\\" \\\\u2014 \\\\u201CIn Progress\\\\u201D tasks stay \\\\u201CIn Progress.\\\\u201D\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Fresh Start\\"}),\\" \\\\u2014 Other unfinished tasks reset for a new day.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Zero Manual Work\\"}),\\" \\\\u2014 Everything happens in the background.\\"]})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"flexible-data-storage\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#flexible-data-storage\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Flexible Data Storage\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Guest Mode\\"}),\\" \\\\u2014 Works immediately with browser storage.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Cloud Sync\\"}),\\" \\\\u2014 Optional Google Drive integration.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Easy Backup\\"}
1),\\" \\\\u2014 Simple JSON file you can copy anywhere.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Portable\\"}),\\" \\\\u2014 Your data travels with you.\\"]})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"reporting--analysis\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#reporting--analysis\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Reporting & Analysis\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Excel Export\\"}),\\" \\\\u2014 Export all your tasks for analysis.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Complete History\\"}),\\" \\\\u2014 Track productivity over time.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Status Tracking\\"}),\\" \\\\u2014 See what you completed and when.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Priority Insights\\"}),\\" \\\\u2014 Understand your prioritization habits.\\"]})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"the-experience\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-experience\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Experience\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"Simplicity First\\"}),\\" \\\\u2014 Clean, minimalist interface. No learning curve. Fast and lightweight. Works beautifully on phone, tablet, and desktop.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"Powerful Yet Simple\\"}),\\" \\\\u2014 Drag-and-drop reordering. Click to edit tasks inline. Easy status and priority management. Full text display \\\\u2014 nothing gets cut off.\\"]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"perfect-for\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#perfect-for\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Perfect For\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:\\"Knowledge workers who want better daily focus.\\"}),(0,e.jsx)(a.li,{children:\\"Freelancers managing multiple projects.\\"}),(0,e.jsx)(a.li,{children:\\"Students organizing coursework and deadlines.\\"}),(0,e.jsx)(a.li,{children:\\"Small teams needing simple task coordination.\\"}),(0,e.jsx)(a.li,{children:\\"Anyone who values simplicity over complexity.\\"})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"great-for\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#great-for\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Great For\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:\\"Daily planning and standups.\\"}),(0,e.jsx)(a.li,{children:\\"Personal productivity tracking.\\"}),(0,e.jsx)(a.li,{children:\\"Small team task management.\\"}),(0,e.jsx)(a.li,{children:\\"Project progress monitoring.\\"}),(0,e.jsx)(a.li,{children:\\"Recurring task workflows.\\"}),(0,e.jsx)(a.li,{children:\\"Long-term goal tracking.\\"})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"daily-flow-vs-traditional-task-managers\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#daily-flow-vs-traditional-task-managers\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Daily Flow vs Traditional Task Managers\\"]}),(0,e.jsxs)(a.table,{children:[(0,e.jsx)(a.thead,{children:(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.th,{children:\\"Feature\\"}),(0,e.jsx)(a.th,{children:\\"Daily Flow\\"}),(0,e.jsx)(a.th,{children:\\"Traditional Task Managers\\"})]})}),(0,e.jsxs)(a.tbody,{children:[(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Focus\\"})}),(0,e.jsx)(a.td,{children:\\"Today-first\\"}),(0,e.jsx)(a.td,{children:\\"Everything at once\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Setup\\"})}),(0,e.jsx)(a.td,{children:\\"Zero setup\\"}),(0,e.jsx)(a.td,{children:\\"Database required\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Automation\\"})}),(0,e.jsx)(a.td,{children:\\"Intelligent carry-forward\\"}),(0,e.jsx)(a.td,{children:\\"Manual migration\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Focus System\\"})}),(0,e.jsx)(a.td,{children:\\"Single active task\\"}),(0,e.jsx)(a.td,{children:\\"Multiple active tasks\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"History\\"})}),(0,e.jsx)(a.td,{children:\\"Complete visibility\\"}
1),(0,e.jsx)(a.td,{children:\\"Often hidden/deleted\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Complexity\\"})}),(0,e.jsx)(a.td,{children:\\"Minimalist\\"}),(0,e.jsx)(a.td,{children:\\"Feature-heavy\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Data Control\\"})}),(0,e.jsx)(a.td,{children:\\"Simple JSON\\"}),(0,e.jsx)(a.td,{children:\\"Complex databases\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Learning Curve\\"})}),(0,e.jsx)(a.td,{children:\\"Instant\\"}),(0,e.jsx)(a.td,{children:\\"Steep\\"})]})]})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"getting-started\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#getting-started\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Getting Started\\"]}),(0,e.jsxs)(a.ol,{children:[(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Open Daily Flow\\"}),\\" \\\\u2014 no sign-up required for guest mode.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Add your first task\\"}),\\" \\\\u2014 type it in and press Enter.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Mark a task \\\\u201CIn Progress\\\\u201D\\"}),\\" \\\\u2014 only one at a time, so you stay focused.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Watch tasks carry forward\\"}),\\" \\\\u2014 when a new day starts, unfinished tasks move to today automatically.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Sign in with Google (optional)\\"}),\\" \\\\u2014 sync across devices whenever you\\\\u2019re ready.\\"]})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"your-data\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#your-data\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Your Data\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Guest Mode\\"}),\\" \\\\u2014 Your data stays in your browser (localStorage).\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Google Drive Sync\\"}),\\" \\\\u2014 Sign in to sync across devices.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Automatic Migration\\"}),\\" \\\\u2014 Sign in after using guest mode and your data moves to Drive automatically.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Export\\"}),\\" \\\\u2014 Export everything to Excel anytime.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Backup\\"}),\\" \\\\u2014 A single data file, easy to back up or move.\\"]})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"the-future-focus-on-today-learn-from-yesterday\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-future-focus-on-today-learn-from-yesterday\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Future: Focus on Today, Learn from Yesterday\\"]}),(0,e.jsxs)(a.p,{children:[\\"With \\",(0,e.jsx)(a.strong,{children:\\"Daily Flow\\"}),\\", you focus on today, keep yesterday as context, and plan tomorrow without drowning in a pile of tasks. No complex setup, no overwhelming interfaces, no manual migration \\\\u2014 just pure, day-first productivity.\\"]}),(0,e.jsx)(a.p,{children:\\"This is more than a tool.\\"}),(0,e.jsx)(a.blockquote,{children:(0,e.jsx)(a.p,{children:\\"It\\\\u2019s where simplicity meets productivity \\\\u2014 a task manager that gets out of your way so you can actually do the work.\\"})})]})}function c(t={}){let{wrapper:a}=t.components||{};return a?(0,e.jsx)(a,{...t,children:(0,e.jsx)(h,{...t})}):h(t)}return v(x);})();\\n;return Component;"},"_id":"blog/daily-flow.mdx","_raw":{"sourceFilePath":"blog/daily-flow.mdx","sourceFileName":"daily-flow.mdx","sourceFileDir":"blog","contentType":"mdx","flattenedPath":"blog/daily-flow"},"type":"Blog","readingTime":{"text":"8 min read","minutes":7.7,"time":462000,"words":1540},"slug":"daily-flow","path":"blog/daily-flow","filePath":"blog/daily-flow.mdx","toc":[{"value":"The Spark: The Weight of Seeing Everything at Once","url":"#the-spark-the-weight-of-seeing-everything-at-once","depth":1},{"value":"The Idea: Today First, History Below","url":"#the-idea-today-first-history-below","depth":2},{"value":"What Problem Are We Solving?","url":"#what-problem-are-we-solving","depth":2},{"value":"How Daily Flow Solves It","url":"#how-daily-flow-solves-it","depth":2},{"value":"How It Works","url":"#how-it-works","depth":2},{"value":"Every Day Starts Fresh","url":"#every-day-starts-fresh","depth":3},{"value":"Focus on One Task at a Time","url":"#focus-on-one-task-at-a-time","depth":3},{"value":"Smart Organization","url":"#smart-organization","depth":3},{"value":"What Makes It Different","url":"#what-makes-it-different","depth":2},{"value":"Key Features","url":"#key-features","depth":2},{"value":"Smart Task Management","url":"#smart-task-management","depth":3},{"value":"Seamless Daily Transitions","url":"#seamless-daily-transitions","depth":3},{"value":"Flexible Data Storage","url":"#flexible-data-storage","depth":3},{"value":"Reporting & Analysis","url":"#reporting--analysis","depth":3},{"value":"The Experience","url":"#the-experience","depth":2},{"value":"Perfect For","url":"#perfect-for","depth":2},{"value":"Great For","url":"#great-for","depth":2},{"value":"Daily Flow vs Traditional Task Managers","url":"#daily-flow-vs-traditional-task-managers","depth":2},{"value":"Getting Started","url":"#getting-started","depth":2},{"value":"Your Data","url":"#your-data","depth":2},{"value":"The Future: Focus on Today, Learn from Yesterday","url":"#the-future-focus-on-today-learn-from-yesterday","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"Daily Flow â A Minimalist, Day-First Task Management System","datePublished":"2026-04-21T00:00:00.000Z","dateModified":"2026-04-21T00:00:00.000Z","description":"Daily Flow is a minimalist, day-first task management system that helps you focus on what matters today. Unfinished tasks carry forward automatically, only one task can be \\"In Progress\\" at a time, and your complete history stays visible.","url":"https://www.devity.in/blog/daily-flow/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/dailyflow-screenshot.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"The Story of DevSync AI â AI-Powered Development Planning Assistant","date":"2025-06-05T00:00:00.000Z","tags":["AI","Development Planning","AI-Powered Development Planning Assistant","devity-engineering"],"keywords":[],"lastmod":"2025-06-05T00:00:00.000Z","draft":true,"summary":"The story of DevSync AI, an AI-powered development planning assistant that helps teams plan and execute their development projects more efficiently. This article provides an overview of the product, its features, and its benefits.","images":"","layout":"PostLayout","canonicalUrl":"https://blog.devity.in/devity-engineering/devsync-ai-powered-development-planning-assistant","faqs":[],"body":{"raw":"\\n# The Spark: A Broken Link Between Product & Code\\n\\nEvery time a product requirement document (PRD) is created, a familiar chaos unfolds in software teams. PMs, tech leads, and developers gather for planning meetings, manually dissecting the PRD into epics, stories, and tasks. Weeks are spent clarifying what needs to be built, which teams are responsible, how the pieces connect, and defining vague specs into actionable work.\\n\\nThen, developers pick up those tasks â often with little visibility into why theyâre doing what theyâre doing, or how their code contributes to the bigger product vision. Context gets lost. Rework happens. Efficiency drops.\\n\\nIn parallel, AI coding tools like Cursor, Copilot, and Cody are getting better at generating code, but they lack the higher-level understanding of product intent and project structure. Theyâre great at writing functions, but not at orchestrating a feature from idea to code.\\n\\nThatâs where **DevSync AI** comes in.\\n\\n## The Idea: Closing the Gap from PRD to Code\\n\\nWhat if we could automate the tedious parts of development planning?\\n\\nWhat if, as soon as a PRD is created, an AI could:\\n\\n- Understand the featureâs goals.\\n- Break it down into actionable tasks.\\n- Map those tasks to system components.\\n- Generate a visual plan for the team.\\n- And even prepare context-rich tasks for AI code tools to execute.\\n\\nDevelopers would no longer have to manually translate product goals into engineering tasks. PMs would save days of planning effort. The entire team would stay aligned, from idea to implementation.\\n\\nThis is the core vision of **DevSync AI**:\\n\\n> Turning product requirements into structured, developer-ready tasks â and connecting them seamlessly to the coding workflow.\\n\\n## What Problem Are We Solving?\\n\\n- Manual, repetitive planning cycles.\\n- Lack of developer context for why a task matters.\\n- Disjointed workflows between product planning and code generation.\\n- Inefficient task assignment & resource allocation.\\n- Wasted time on figuring out âwhat to do nextâ.\\n\\n## How DevSync AI Solves It\\n\\nâ
**AI-Powered PRD Parsing**: \\nReads and understands the PRD, extracting goals, epics, stories, and subtasks.\\n\\nâ
**System Component Mapping**: \\nIdentifies which parts of the codebase are impacted and structures work accordingly.\\n\\nâ
**Visual Development Plan (Mind Map + Kanban)**: \\nGives developers and PMs a clear overview of feature progress and architecture impact.\\n\\nâ
**AI-Assisted Task Assignment**: \\nAuto-assigns tasks based on developer skills, workload, and past performance.\\n\\nâ
**Code Generation Integration**: \\nFeeds structured tasks into tools like Cursor, Copilot, or Cody for code generation â with full context.\\n\\nâ
**Continuous Learning & Optimization**: \\nLearns from team feedback, improving future breakdowns and assignments.\\n\\n## The Future: The AI Tech Lead & Project Manager\\n\\nWith **DevSync AI**, teams can focus on building, not planning. Developers gain clarity. PMs stay in control. AI handles the heavy lifting of translating product intent into executable work â
1closing the gap from PRD to Code.\\n\\nThis is more than a tool.\\n\\n> Itâs the future of software development planning.\\n","code":"var Component=(()=>{var p=Object.create;var i=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var f=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),v=(t,e)=>{for(var a in e)i(t,a,{get:e[a],enumerable:!0})},l=(t,e,a,o)=>{if(e&&typeof e==\\"object\\"||typeof e==\\"function\\")for(let r of u(e))!w.call(t,r)&&r!==a&&i(t,r,{get:()=>e[r],enumerable:!(o=g(e,r))||o.enumerable});return t};var k=(t,e,a)=>(a=t!=null?p(m(t)):{},l(e||!t||!t.__esModule?i(a,\\"default\\",{value:t,enumerable:!0}):a,t)),b=t=>l(i({},\\"__esModule\\",{value:!0}),t);var d=f((A,s)=>{s.exports=_jsx_runtime});var x={};v(x,{default:()=>h,frontmatter:()=>y});var n=k(d()),y={title:\\"The Story of DevSync AI \\\\u2014 AI-Powered Development Planning Assistant\\",date:\\"2025-06-05\\",lastmod:\\"2025-06-05\\",tags:[\\"AI\\",\\"Development Planning\\",\\"AI-Powered Development Planning Assistant\\",\\"devity-engineering\\"],draft:!0,images:\\"\\",summary:\\"The story of DevSync AI, an AI-powered development planning assistant that helps teams plan and execute their development projects more efficiently. This article provides an overview of the product, its features, and its benefits.\\",layout:\\"PostLayout\\",canonicalUrl:\\"https://blog.devity.in/devity-engineering/devsync-ai-powered-development-planning-assistant\\"};function c(t){let e={a:\\"a\\",blockquote:\\"blockquote\\",br:\\"br\\",h1:\\"h1\\",h2:\\"h2\\",li:\\"li\\",p:\\"p\\",path:\\"path\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",ul:\\"ul\\",...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(e.h1,{className:\\"content-header\\",id:\\"the-spark-a-broken-link-between-product--code\\",children:[(0,n.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-spark-a-broken-link-between-product--code\\",tabIndex:\\"-1\\",children:(0,n.jsx)(n.Fragment,{children:(0,n.jsx)(e.span,{className:\\"content-header-link\\",children:(0,n.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,n.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,n.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Spark: A Broken Link Between Product & Code\\"]}),(0,n.jsx)(e.p,{children:\\"Every time a product requirement document (PRD) is created, a familiar chaos unfolds in software teams. PMs, tech leads, and developers gather for planning meetings, manually dissecting the PRD into epics, stories, and tasks. Weeks are spent clarifying what needs to be built, which teams are responsible, how the pieces connect, and defining vague specs into actionable work.\\"}),(0,n.jsx)(e.p,{children:\\"Then, developers pick up those tasks \\\\u2014 often with little visibility into why they\\\\u2019re doing what they\\\\u2019re doing, or how their code contributes to the bigger product vision. Context gets lost. Rework happens. Efficiency drops.\\"}),(0,n.jsx)(e.p,{children:\\"In parallel, AI coding tools like Cursor, Copilot, and Cody are getting better at generating code, but they lack the higher-level understanding of product intent and project structure. They\\\\u2019re great at writing functions, but not at orchestrating a feature from idea to code.\\"}),(0,n.jsxs)(e.p,{children:[\\"That\\\\u2019s where \\",(0,n.jsx)(e.strong,{children:\\"DevSync AI\\"}),\\" comes in.\\"]}),(0,n.jsxs)(e.h2,{className:\\"content-header\\",id:\\"the-idea-closing-the-gap-from-prd-to-code\\",children:[(0,n.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-idea-closing-the-gap-from-prd-to-code\\",tabIndex:\\"-1\\",children:(0,n.jsx)(n.Fragment,{children:(0,n.jsx)(e.span,{className:\\"content-header-link\\",children:(0,n.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,n.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,n.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Idea: Closing the Gap from PRD to Code\\"]}),(0,n.jsx)(e.p,{children:\\"What if we could automate the tedious parts of development planning?\\"}),(0,n.jsx)(e.p,{children:\\"What if, as soon as a PRD is created, an AI could:\\"}),(0,n.jsxs)(e.ul,{children:[(0,n.jsx)(e.li,{children:\\"Understand the feature\\\\u2019s goals.\\"}),(0,n.jsx)(e.li,{children:\\"Break it down into actionable tasks.\\"}),(0,n.jsx)(e.li,{children:\\"Map those tasks to system components.\\"}),(0,n.jsx)(e.li,{children:\\"Generate a visual plan for the team.\\"}),(0,n.jsx)(e.li,{children:\\"And even prepare context-rich tasks for AI code tools to execute.\\"})]}),(0,n.jsx)(e.p,{children:\\"Developers would no longer have to manually translate product goals into engineering tasks. PMs would save days of planning effort. The entire team would stay aligned, from idea to implementation.\\"}),(0,n.jsxs)(e.p,{children:[\\"This is the core vision of \\",(0,n.jsx)(e.strong,{children:\\"DevSync AI\\"}),\\":\\"]}),(0,n.jsx)(e.blockquote,{children:(0,n.jsx)(e.p,{children:\\"Turning product requirements into structured, developer-ready tasks \\\\u2014 and connecting them seamlessly to the coding workflow.\\"})}),(0,n.jsxs)(e.h2,{className:\\"content-header\\",id:\\"what-problem-are-we-solving\\",children:[(0,n.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#what-problem-are-we-solving\\",tabIndex:\\"-1\\",children:(0,n.jsx)(n.Fragment,{children:(0,n.jsx)(e.span,{className:\\"content-header-link\\",children:(0,n.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,n.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,n.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Problem Are We Solving?\\"]}),(0,n.jsxs)(e.ul,{children:[(0,n.jsx)(e.li,{children:\\"Manual, repetitive planning cycles.\\"}),(0,n.jsx)(e.li,{children:\\"Lack of developer context for why a task matters.\\"}),(0,n.jsx)(e.li,{children:\\"Disjointed workflows between product planning and code generation.\\"}),(0,n.jsx)(e.li,{children:\\"Inefficient task assignment & resource allocation.\\"}),(0,n.jsx)(e.li,{children:\\"Wasted time on figuring out \\\\u201Cwhat to do next\\\\u201D.\\"})]}),(0,n.jsxs)(e.h2,{className:\\"content-header\\",id:\\"how-devsync-ai-solves-it\\",children:[(0,n.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#how-devsync-ai-solves-it\\",tabIndex:\\"-1\\",children:(0,n.jsx)(n.Fragment,{children:(0,n.jsx)(e.span,{className:\\"content-header-link\\",children:(0,n.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,n.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,n.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"How DevSync AI Solves It\\"]}),(0,n.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,n.jsx)(e.strong,{children:\\"AI-Powered PRD Parsing\\"}),\\":\\",(0,n.jsx)(e.br,{}),\\"Reads and understands the PRD, extracting goals, epics, stories, and subtasks.\\"]}
1),(0,n.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,n.jsx)(e.strong,{children:\\"System Component Mapping\\"}),\\":\\",(0,n.jsx)(e.br,{}),\\"Identifies which parts of the codebase are impacted and structures work accordingly.\\"]}),(0,n.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,n.jsx)(e.strong,{children:\\"Visual Development Plan (Mind Map + Kanban)\\"}),\\":\\",(0,n.jsx)(e.br,{}),\\"Gives developers and PMs a clear overview of feature progress and architecture impact.\\"]}),(0,n.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,n.jsx)(e.strong,{children:\\"AI-Assisted Task Assignment\\"}),\\":\\",(0,n.jsx)(e.br,{}),\\"Auto-assigns tasks based on developer skills, workload, and past performance.\\"]}),(0,n.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,n.jsx)(e.strong,{children:\\"Code Generation Integration\\"}),\\":\\",(0,n.jsx)(e.br,{}),\\"Feeds structured tasks into tools like Cursor, Copilot, or Cody for code generation \\\\u2014 with full context.\\"]}),(0,n.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,n.jsx)(e.strong,{children:\\"Continuous Learning & Optimization\\"}),\\":\\",(0,n.jsx)(e.br,{}),\\"Learns from team feedback, improving future breakdowns and assignments.\\"]}),(0,n.jsxs)(e.h2,{className:\\"content-header\\",id:\\"the-future-the-ai-tech-lead--project-manager\\",children:[(0,n.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-future-the-ai-tech-lead--project-manager\\",tabIndex:\\"-1\\",children:(0,n.jsx)(n.Fragment,{children:(0,n.jsx)(e.span,{className:\\"content-header-link\\",children:(0,n.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,n.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,n.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Future: The AI Tech Lead & Project Manager\\"]}),(0,n.jsxs)(e.p,{children:[\\"With \\",(0,n.jsx)(e.strong,{children:\\"DevSync AI\\"}),\\", teams can focus on building, not planning. Developers gain clarity. PMs stay in control. AI handles the heavy lifting of translating product intent into executable work \\\\u2014 closing the gap from PRD to Code.\\"]}),(0,n.jsx)(e.p,{children:\\"This is more than a tool.\\"}),(0,n.jsx)(e.blockquote,{children:(0,n.jsx)(e.p,{children:\\"It\\\\u2019s the future of software development planning.\\"})})]})}function h(t={}){let{wrapper:e}=t.components||{};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(c,{...t})}):c(t)}return b(x);})();\\n;return Component;"},"_id":"blog/devsync-ai-powered-development-planning-assistant.mdx","_raw":{"sourceFilePath":"blog/devsync-ai-powered-development-planning-assistant.mdx","sourceFileName":"devsync-ai-powered-development-planning-assistant.mdx","sourceFileDir":"blog","contentType":"mdx","flattenedPath":"blog/devsync-ai-powered-development-planning-assistant"},"type":"Blog","readingTime":{"text":"3 min read","minutes":2.47,"time":148200,"words":494},"slug":"devsync-ai-powered-development-planning-assistant","path":"blog/devsync-ai-powered-development-planning-assistant","filePath":"blog/devsync-ai-powered-development-planning-assistant.mdx","toc":[{"value":"The Spark: A Broken Link Between Product & Code","url":"#the-spark-a-broken-link-between-product--code","depth":1},{"value":"The Idea: Closing the Gap from PRD to Code","url":"#the-idea-closing-the-gap-from-prd-to-code","depth":2},{"value":"What Problem Are We Solving?","url":"#what-problem-are-we-solving-1","depth":2},{"value":"How DevSync AI Solves It","url":"#how-devsync-ai-solves-it","depth":2},{"value":"The Future: The AI Tech Lead & Project Manager","url":"#the-future-the-ai-tech-lead--project-manager","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"The Story of DevSync AI â AI-Powered Development Planning Assistant","datePublished":"2025-06-05T00:00:00.000Z","dateModified":"2025-06-05T00:00:00.000Z","description":"The story of DevSync AI, an AI-powered development planning assistant that helps teams plan and execute their development projects more efficiently. This article provides an overview of the product, its features, and its benefits.","url":"https://www.devity.in/blog/devsync-ai-powered-development-planning-assistant/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/devity-blog.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"Invoice Maker â Text-First Receipt & Invoice Creator","date":"2025-01-15T00:00:00.000Z","tags":["Web App","Invoice Generator","Receipt Creator","Text-Based","PWA","devity-engineering"],"keywords":[],"lastmod":"2025-01-15T00:00:00.000Z","draft":true,"summary":"Invoice Maker, a simple, fast, text-based receipt and invoice generator built with Next.js. Create and share receipts instantly - all in your browser, completely offline, no backend required.","images":"/static/images/invoice.devity.in-screenshot.png","layout":"PostLayout","canonicalUrl":"","faqs":[],"body":{"raw":"\\n\\n\\n# The Spark: The Heavy Weight of Modern Invoices\\n\\nEvery time you need to send a receipt or invoice, a familiar friction unfolds. You open a complex invoice tool, fill out dozens of fields, wait for PDF generation, struggle with file sizes, and then wonder: \\"Will this even work when I paste it into WhatsApp?\\"\\n\\nMost invoice tools are built for print. They generate heavy PDFs, require image uploads, and create files that are hard to share via text messages or instant messaging apps. They\'re designed for formal business documents, not for the quick, lightweight receipts that most people actually need to send.\\n\\nThen, when you try to share that PDF via SMS or WhatsApp, it either fails to send, takes forever to load, or the recipient can\'t open it. You end up taking screenshots, converting formats, or giving up and typing the receipt manually.\\n\\nThat\'s where [**Invoice Maker**](https://invoice.devity.in) comes in.\\n\\n## The Idea: Text-First, Share-Everywhere Receipts\\n\\nWhat if invoices were optimized for how people actually share them?\\n\\nWhat if, instead of generating heavy PDFs or images, we created receipts that:\\n\\n- Work perfectly in text messages and WhatsApp.\\n- Are instantly shareable without file attachments.\\n- Load fast, work offline, and require no backend.\\n- Show only what matters â no empty fields cluttering the receipt.\\n- Support 30+ currencies and multiple templates.\\n- Can still export as PDF or image when needed.\\n\\nSmall businesses, freelancers, and individuals would no longer struggle with complex invoice tools for simple receipts. Sharing would be as easy as copying text. Everything would work offline, respecting privacy with zero cloud dependencies.\\n\\nThis is the core vision of **Invoice Maker**:\\n\\n> Turning receipt creation into a simple, text-first experience â optimized for how people actually share invoices today.\\n\\n## What Problem Are We Solving?\\n\\n- Heavy, complex invoice tools for simple receipt needs.\\n- PDFs and images that fail to share via SMS/WhatsApp.\\n- Slow, bloated interfaces that require internet connectivity.\\n- Cluttered receipts showing empty fields and unnecessary information.\\n- Privacy concerns with cloud-based invoice services.\\n- Over-engineered solutions for lightweight use cases.\\n\\n## How Invoice Maker Solves It\\n\\nâ
**Text-First Design**: \\nReceipts are optimized for text-based sharing (SMS, WhatsApp, Email). Perfect for quick, lightweight receipts that work everywhere without heavy PDFs or images.\\n\\nâ
**Smart Field Display**: \\nOnly shows fields that are actually filled by the user. No empty fields cluttering the receipt, keeping it clean and professional.\\n\\nâ
**30+ Currency Support**: \\nSupport for INR, USD, EUR, GBP, JPY, and 25+ more currencies. Change currency instantly in the preview toolbar with INR as the default.\\n\\nâ
**Four Text-Optimized Templates**: \\nChoose from Plain Text (perfect for SMS/WhatsApp), Bordered Text Receipt, Modern Card Layout, or Compact Minimal Layout. All templates are lightweight, theme-aware, and share-ready.\\n\\nâ
**Instant Sharing & Export**: \\nCopy text to clipboard (primary method), share to WhatsApp, use native Web Share API, or export as PNG, PDF, or HTML when needed.\\n\\nâ
**100% Offline & Privacy-First**: \\nWorks completely offline with no backend required. Stores up to 100 receipts locally in your browser. No cloud sync, no tracking, no data leaving your device.\\n\\nâ
**PWA Ready**: \\nFully configured Progressive Web App. Install on Android/iOS, works offline, cached assets, app-like experience.\\n\\nâ
**Auto-Generated Receipt Numbers**: \\nSmart receipt numbering (format: RN-YYYYMMDD-001) with automatic sequential tracking per day.\\n\\n## The Future: Simple, Fast, Shareable Receipts\\n\\nWith **Invoice Maker**, creating and sharing receipts is as simple as filling a form and copying text. No complex tools. No heavy files. No privacy concerns. Just fast, lightweight receipts that work everywhere.\\n\\nThis is more than a tool.\\n\\n> It\'s the future of simple invoice creation â text-first, share-everywhere, privacy-respecting.\\n","code":"var Component=(()=>{var p=Object.create;var n=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var v=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),w=(t,e)=>{for(var r in e)n(t,r,{get:e[r],enumerable:!0})},o=(t,e,r,l)=>{if(e&&typeof e==\\"object\\"||typeof e==\\"function\\")for(let a of m(e))!f.call(t,a)&&a!==r&&n(t,a,{get:()=>e[a],enumerable:!(l=g(e,a))||l.enumerable});return t};var y=(t,e,r)=>(r=t!=null?p(u(t)):{}
1,o(e||!t||!t.__esModule?n(r,\\"default\\",{value:t,enumerable:!0}):r,t)),x=t=>o(n({},\\"__esModule\\",{value:!0}),t);var c=v((I,s)=>{s.exports=_jsx_runtime});var M={};w(M,{default:()=>d,frontmatter:()=>b});var i=y(c()),b={title:\\"Invoice Maker \\\\u2014 Text-First Receipt & Invoice Creator\\",date:\\"2025-01-15\\",lastmod:\\"2025-01-15\\",tags:[\\"Web App\\",\\"Invoice Generator\\",\\"Receipt Creator\\",\\"Text-Based\\",\\"PWA\\",\\"devity-engineering\\"],draft:!0,images:\\"/static/images/invoice.devity.in-screenshot.png\\",summary:\\"Invoice Maker, a simple, fast, text-based receipt and invoice generator built with Next.js. Create and share receipts instantly - all in your browser, completely offline, no backend required.\\",layout:\\"PostLayout\\",canonicalUrl:\\"\\"};function h(t){let e={a:\\"a\\",blockquote:\\"blockquote\\",br:\\"br\\",div:\\"div\\",h1:\\"h1\\",h2:\\"h2\\",li:\\"li\\",p:\\"p\\",path:\\"path\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",ul:\\"ul\\",...t.components},{Image:r}=e;return r||k(\\"Image\\",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(e.div,{children:(0,i.jsx)(r,{alt:\\"Invoice Maker \\\\u2014 Text-First Receipt & Invoice Creator \\",src:\\"/static/images/invoice.devity.in-screenshot.png\\",width:\\"2562\\",height:\\"1472\\"})}),(0,i.jsxs)(e.h1,{className:\\"content-header\\",id:\\"the-spark-the-heavy-weight-of-modern-invoices\\",children:[(0,i.jsx)(e.a,{href:\\"#the-spark-the-heavy-weight-of-modern-invoices\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,i.jsx)(i.Fragment,{children:(0,i.jsx)(e.span,{className:\\"content-header-link\\",children:(0,i.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,i.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,i.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Spark: The Heavy Weight of Modern Invoices\\"]}),(0,i.jsx)(e.p,{children:\'Every time you need to send a receipt or invoice, a familiar friction unfolds. You open a complex invoice tool, fill out dozens of fields, wait for PDF generation, struggle with file sizes, and then wonder: \\"Will this even work when I paste it into WhatsApp?\\"\'}),(0,i.jsx)(e.p,{children:\\"Most invoice tools are built for print. They generate heavy PDFs, require image uploads, and create files that are hard to share via text messages or instant messaging apps. They\'re designed for formal business documents, not for the quick, lightweight receipts that most people actually need to send.\\"}),(0,i.jsx)(e.p,{children:\\"Then, when you try to share that PDF via SMS or WhatsApp, it either fails to send, takes forever to load, or the recipient can\'t open it. You end up taking screenshots, converting formats, or giving up and typing the receipt manually.\\"}),(0,i.jsxs)(e.p,{children:[\\"That\'s where \\",(0,i.jsx)(e.a,{href:\\"https://invoice.devity.in\\",children:(0,i.jsx)(e.strong,{children:\\"Invoice Maker\\"})}),\\" comes in.\\"]}),(0,i.jsxs)(e.h2,{className:\\"content-header\\",id:\\"the-idea-text-first-share-everywhere-receipts\\",children:[(0,i.jsx)(e.a,{href:\\"#the-idea-text-first-share-everywhere-receipts\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,i.jsx)(i.Fragment,{children:(0,i.jsx)(e.span,{className:\\"content-header-link\\",children:(0,i.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,i.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,i.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Idea: Text-First, Share-Everywhere Receipts\\"]}),(0,i.jsx)(e.p,{children:\\"What if invoices were optimized for how people actually share them?\\"}),(0,i.jsx)(e.p,{children:\\"What if, instead of generating heavy PDFs or images, we created receipts that:\\"}),(0,i.jsxs)(e.ul,{children:[(0,i.jsx)(e.li,{children:\\"Work perfectly in text messages and WhatsApp.\\"}),(0,i.jsx)(e.li,{children:\\"Are instantly shareable without file attachments.\\"}),(0,i.jsx)(e.li,{children:\\"Load fast, work offline, and require no backend.\\"}),(0,i.jsx)(e.li,{children:\\"Show only what matters \\\\u2014 no empty fields cluttering the receipt.\\"}),(0,i.jsx)(e.li,{children:\\"Support 30+ currencies and multiple templates.\\"}),(0,i.jsx)(e.li,{children:\\"Can still export as PDF or image when needed.\\"})]}),(0,i.jsx)(e.p,{children:\\"Small businesses, freelancers, and individuals would no longer struggle with complex invoice tools for simple receipts. Sharing would be as easy as copying text. Everything would work offline, respecting privacy with zero cloud dependencies.\\"}),(0,i.jsxs)(e.p,{children:[\\"This is the core vision of \\",(0,i.jsx)(e.strong,{children:\\"Invoice Maker\\"}),\\":\\"]}),(0,i.jsx)(e.blockquote,{children:(0,i.jsx)(e.p,{children:\\"Turning receipt creation into a simple, text-first experience \\\\u2014 optimized for how people actually share invoices today.\\"})}),(0,i.jsxs)(e.h2,{className:\\"content-header\\",id:\\"what-problem-are-we-solving\\",children:[(0,i.jsx)(e.a,{href:\\"#what-problem-are-we-solving\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,i.jsx)(i.Fragment,{children:(0,i.jsx)(e.span,{className:\\"content-header-link\\",children:(0,i.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,i.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,i.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Problem Are We Solving?\\"]}),(0,i.jsxs)(e.ul,{children:[(0,i.jsx)(e.li,{children:\\"Heavy, complex invoice tools for simple receipt needs.\\"}),(0,i.jsx)(e.li,{children:\\"PDFs and images that fail to share via SMS/WhatsApp.\\"}),(0,i.jsx)(e.li,{children:\\"Slow, bloated interfaces that require internet connectivity.\\"}),(0,i.jsx)(e.li,{children:\\"Cluttered receipts showing empty fields and unnecessary information.\\"}),(0,i.jsx)(e.li,{children:\\"Privacy concerns with cloud-based invoice services.\\"}),(0,i.jsx)(e.li,{children:\\"Over-engineered solutions for lightweight use cases.\\"})]}),(0,i.jsxs)(e.h2,{className:\\"content-header\\",id:\\"how-invoice-maker-solves-it\\",children:[(0,i.jsx)(e.a,{href:\\"#how-invoice-maker-solves-it\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,i.jsx)(i.Fragment,{children:(0,i.jsx)(e.span,{className:\\"content-header-link\\",children:(0,i.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,i.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,i.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"How Invoice Maker Solves It\\"]}),(0,i.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,i.jsx)(e.strong,{children:\\"Text-First Design\\"}),\\":\\",(0,i.jsx)(e.br,{}),\\"Receipts are optimized for text-based sharing (SMS, WhatsApp, Email). Perfect for quick, lightweight receipts that work everywhere without heavy PDFs or images.\\"]}),(0,i.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,i.jsx)(e.strong,{children:\\"Smart Field Display\\"}),\\":\\",(0,i.jsx)(e.br,{}),\\"Only shows fields that are actually filled by the user. No empty fields cluttering the receipt, keeping it clean and professional.\\"]}),(0,i.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,i.jsx)(e.strong,{children:\\"30+ Currency Support\\"}),\\":\\",(0,i.jsx)(e.br,{}),\\"Support for INR, USD, EUR, GBP, JPY, and 25+ more currencies. Change currency instantly in the preview toolbar with INR as the default.\\"]}),(0,i.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,i.jsx)(e.strong,{children:\\"Four Text-Optimized Templates\\"}),\\":\\",(0,i.jsx)(e.br,{}),\\"Choose from Plain Text (perfect for SMS/WhatsApp), Bordered Text Receipt, Modern Card Layout, or Compact Minimal Layout. All templates are lightweight, theme-aware, and share-ready.\\"]}),(0,i.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,i.jsx)(e.strong,{children:\\"Instant Sharing & Export\\"}),\\":\\",(0,i.jsx)(e.br,{}),\\"Copy text to clipboard (primary method), share to WhatsApp, use native Web Share API, or export as PNG, PDF, or HTML when needed.\\"]}),(0,i.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,i.jsx)(e.strong,{children:\\"100% Offline & Privacy-First\\"}),\\":\\",(0,i.jsx)(e.br,{}),\\"Works completely offline with no backend required. Stores up to 100 receipts locally in your browser. No cloud sync, no tracking, no data leaving your device.\\"]}),(0,i.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,i.jsx)(e.strong,{children:\\"PWA Ready\\"}),\\":\\",(0,i.jsx)(e.br,{}),\\"Fully configured Progressive Web App. Install on Android/iOS, works offline, cached assets, app-like experience.\\"]}),(0,i.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,i.jsx)(e.strong,{children:\\"Auto-Generated Receipt Numbers\\"}),\\":\\",(0,i.jsx)(e.br,{}),\\"Smart receipt numbering (format: RN-YYYYMMDD-001) with automatic sequential tracking per day.\\"]}),(0,i.jsxs)(e.h2,{className:\\"content-header\\",id:\\"the-future-simple-fast-shareable-receipts\\",children:[(0,i.jsx)(e.a,{href:\\"#the-future-simple-fast-shareable-receipts\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,i.jsx)(i.Fragment,{children:(0,i.jsx)(e.span,{className:\\"content-header-link\\",children:(0,i.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,i.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,i.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Future: Simple, Fast, Shareable Receipts\\"]}),(0,i.jsxs)(e.p,{children:[\\"With \\",(0,i.jsx)(e.strong,{children:\\"Invoice Maker\\"}),\\", creating and sharing receipts is as simple as filling a form and copying text. No complex tools. No heavy files. No privacy concerns. Just fast, lightweight receipts that work everywhere.\\"]}),(0,i.jsx)(e.p,{children:\\"This is more than a tool.\\"}),(0,i.jsx)(e.blockquote,{children:(0,i.jsx)(e.p,{children:\\"It\'s the future of simple invoice creation \\\\u2014 text-first, share-everywhere, privacy-respecting.\\"})})]})}function d(t={}){let{wrapper:e}=t.components||{};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(h,{...t})}):h(t)}function k(t,e){throw new Error(\\"Expected \\"+(e?\\"component\\":\\"object\\")+\\" `\\"+t+\\"` to be defined: you likely forgot to import, pass, or provide it.\\")}return x(M);})();\\n;return Component;"},"_id":"blog/free-invoice-maker.mdx","_raw":{"sourceFilePath":"blog/free-invoice-maker.mdx","sourceFileName":"free-invoice-maker.mdx","sourceFileDir":"blog","contentType":"mdx","flattenedPath":"blog/free-invoice-maker"},"type":"Blog","readingTime":{"text":"4 min read","minutes":3.095,"time":185700,"words":619},"slug":"free-invoice-maker","path":"blog/free-invoice-maker","filePath":"blog/free-invoice-maker.mdx","toc":[{"value":"The Spark: The Heavy Weight of Modern Invoices","url":"#the-spark-the-heavy-weight-of-modern-invoices","depth":1},{"value":"The Idea: Text-First, Share-Everywhere Receipts","url":"#the-idea-text-first-share-everywhere-receipts","depth":2},{"value":"What Problem Are We Solving?","url":"#what-problem-are-we-solving-2","depth":2},{"value":"How Invoice Maker Solves It","url":"#how-invoice-maker-solves-it","depth":2},{"value":"The Future: Simple, Fast, Shareable Receipts","url":"#the-future-simple-fast-shareable-receipts","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"Invoice Maker â Text-First Receipt & Invoice Creator","datePublished":"2025-01-15T00:00:00.000Z","dateModified":"2025-01-15T00:00:00.000Z","description":"Invoice Maker, a simple, fast, text-based receipt and invoice generator built with Next.js. Create and share receipts instantly - all in your browser, completely offline, no backend required.","url":"https://www.devity.in/blog/free-invoice-maker/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/invoice.devity.in-screenshot.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"Free Resume Builder â Markdown-Based Professional Resume Creator","date":"2025-01-15T00:00:00.000Z","tags":["Web App","Resume Builder","Markdown","PDF Export","Next.js","devity-engineering"],"keywords":[],"lastmod":"2025-01-15T00:00:00.000Z","draft":false,"summary":"Free Resume Builder, a modern, markdown-based resume creator built with Next.js. Create professional resumes with real-time preview, 10+ templates, and PDF export capabilities â all in your browser.","images":"/static/images/resume.devity.in-screenshot.png","layout":"PostLayout","canonicalUrl":"","faqs":[],"body":{"raw":"\\n\\n\\n# The Spark: The Complexity of Modern Resume Building\\n\\nEvery time you need to update your resume, a fam
1iliar struggle unfolds. You open a complex resume builder, navigate through dozens of form fields, struggle with rigid templates, wait for PDF generation, and then wonder: \\"Why is this so complicated when I just want to write my experience?\\"\\n\\nMost resume builders are built for templates. They force you into predefined layouts, require you to fill out endless forms, and create resumes that look generic and templated. They\'re designed for visual editing, not for people who want to write and iterate quickly.\\n\\nThen, when you try to customize the design, you\'re limited to what the template allows. You can\'t easily rearrange sections, change fonts, or adjust spacing. You end up fighting with the interface, copying content between tools, or giving up and using a basic Word document.\\n\\nThat\'s where [**Free Resume Builder**](https://resume.devity.in) comes in.\\n\\n## The Idea: Markdown-First, Design-Flexible Resumes\\n\\nWhat if resumes were optimized for how people actually write them?\\n\\nWhat if, instead of complex form-based editors, we created a resume builder that:\\n\\n- Lets you write in markdown â the simplest, most natural way to write.\\n- Shows real-time preview as you type.\\n- Offers 10+ professional templates that you can switch instantly.\\n- Allows complete design customization â colors, fonts, spacing, layout.\\n- Generates high-quality PDFs when you\'re ready.\\n- Works fast, works offline, and requires no backend.\\n- Supports profile pictures with customizable size and position.\\n\\nJob seekers, freelancers, and professionals would no longer struggle with rigid resume builders. Writing would be as simple as typing markdown. Design would be flexible and customizable. Everything would work offline, respecting privacy with zero cloud dependencies.\\n\\nThis is the core vision of **Free Resume Builder**:\\n\\n> Turning resume creation into a simple, markdown-first experience â with the flexibility to customize every aspect of the design.\\n\\n## What Problem Are We Solving?\\n\\n- Complex, form-based resume builders that slow down the writing process.\\n- Rigid templates that limit customization and personalization.\\n- Slow, bloated interfaces that require constant internet connectivity.\\n- Generic-looking resumes that all look the same.\\n- Limited design control â can\'t easily change colors, fonts, or spacing.\\n- Privacy concerns with cloud-based resume services storing your data.\\n- Over-engineered solutions that make simple resume updates a chore.\\n\\n## How Free Resume Builder Solves It\\n\\nâ
**Markdown-Based Editing**: \\nWrite your resume in markdown with slash commands for quick formatting. No complex forms, no rigid structure â just write naturally and see it formatted instantly.\\n\\nâ
**10 Professional Templates**: \\nChoose from Standard, Modern, Minimalist, Professional, Elegant, Creative, Tech, Clean, Classic, and Serif templates. Switch between templates instantly to find the perfect look.\\n\\nâ
**Real-Time Preview**: \\nSee your changes instantly as you type. No waiting, no refresh â just write and watch your resume come to life in real-time.\\n\\nâ
**Complete Design Customization**: \\nCustomize colors, fonts, spacing, layout, title alignment, and more. Full control over every aspect of your resume\'s appearance.\\n\\nâ
**High-Quality PDF Export**: \\nDownload your resume as a high-quality PDF when you\'re ready. Perfect for job applications, LinkedIn, or printing.\\n\\nâ
**Import/Export Markdown**: \\nImport existing markdown files or export your resume as markdown. Your resume data stays portable and under your control.\\n\\nâ
**Responsive Design**: \\nWorks seamlessly on desktop and mobile devices. Edit your resume from anywhere, on any device.\\n\\nâ
**Picture Support**: \\nAdd profile pictures with customizable size, position, and style. Make your resume stand out with a professional photo.\\n\\nâ
**Fast & Lightweight**: \\nBuilt with Next.js for optimal performance. Fast loading, smooth editing, and instant preview updates.\\n\\nâ
**100% Offline & Privacy-First**: \\nWorks completely offline with no backend required. Your resume data stays in your browser. No cloud sync, no tracking, no data leaving your device.\\n\\n## The Future: Simple, Fast, Customizable Resumes\\n\\nWith **Free Resume Builder**, creating and updating resumes is as simple as writing markdown and customizing the design. No complex forms. No rigid templates. No privacy concerns. Just fast, flexible resume creation that works everywhere.\\n\\nThis is more than a tool.\\n\\n> It\'s the future of resume creation â markdown-first, design-flexible, privacy-respecting.\\n","code":"var Component=(()=>{var u=Object.create;var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var f=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),y=(i,e)=>{for(var t in e)a(i,t,{get:e[t],enumerable:!0})},s=(i,e,t,o)=>{if(e&&typeof e==\\"object\\"||typeof e==\\"function\\")for(let n of p(e))!w.call(i,n)&&n!==t&&a(i,n,{get:()=>e[n],enumerable:!(o=m(e,n))||o.enumerable});return i};var b=(i,e,t)=>(t=i!=null?u(g(i)):{},s(e||!i||!i.__esModule?a(t,\\"default\\",{value:i,enumerable:!0}):t,i)),v=i=>s(a({}
1,\\"__esModule\\",{value:!0}),i);var d=f((F,l)=>{l.exports=_jsx_runtime});var M={};y(M,{default:()=>h,frontmatter:()=>k});var r=b(d()),k={title:\\"Free Resume Builder \\\\u2014 Markdown-Based Professional Resume Creator\\",date:\\"2025-01-15\\",lastmod:\\"2025-01-15\\",tags:[\\"Web App\\",\\"Resume Builder\\",\\"Markdown\\",\\"PDF Export\\",\\"Next.js\\",\\"devity-engineering\\"],draft:!1,images:\\"/static/images/resume.devity.in-screenshot.png\\",summary:\\"Free Resume Builder, a modern, markdown-based resume creator built with Next.js. Create professional resumes with real-time preview, 10+ templates, and PDF export capabilities \\\\u2014 all in your browser.\\",layout:\\"PostLayout\\",canonicalUrl:\\"\\"};function c(i){let e={a:\\"a\\",blockquote:\\"blockquote\\",br:\\"br\\",div:\\"div\\",h1:\\"h1\\",h2:\\"h2\\",li:\\"li\\",p:\\"p\\",path:\\"path\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",ul:\\"ul\\",...i.components},{Image:t}=e;return t||x(\\"Image\\",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.div,{children:(0,r.jsx)(t,{alt:\\"Free Resume Builder \\\\u2014 Markdown-Based Professional Resume Creator \\",src:\\"/static/images/resume.devity.in-screenshot.png\\",width:\\"2726\\",height:\\"1450\\"})}),(0,r.jsxs)(e.h1,{className:\\"content-header\\",id:\\"the-spark-the-complexity-of-modern-resume-building\\",children:[(0,r.jsx)(e.a,{href:\\"#the-spark-the-complexity-of-modern-resume-building\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(e.span,{className:\\"content-header-link\\",children:(0,r.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,r.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,r.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Spark: The Complexity of Modern Resume Building\\"]}),(0,r.jsx)(e.p,{children:\'Every time you need to update your resume, a familiar struggle unfolds. You open a complex resume builder, navigate through dozens of form fields, struggle with rigid templates, wait for PDF generation, and then wonder: \\"Why is this so complicated when I just want to write my experience?\\"\'}),(0,r.jsx)(e.p,{children:\\"Most resume builders are built for templates. They force you into predefined layouts, require you to fill out endless forms, and create resumes that look generic and templated. They\'re designed for visual editing, not for people who want to write and iterate quickly.\\"}),(0,r.jsx)(e.p,{children:\\"Then, when you try to customize the design, you\'re limited to what the template allows. You can\'t easily rearrange sections, change fonts, or adjust spacing. You end up fighting with the interface, copying content between tools, or giving up and using a basic Word document.\\"}),(0,r.jsxs)(e.p,{children:[\\"That\'s where \\",(0,r.jsx)(e.a,{href:\\"https://resume.devity.in\\",children:(0,r.jsx)(e.strong,{children:\\"Free Resume Builder\\"})}),\\" comes in.\\"]}),(0,r.jsxs)(e.h2,{className:\\"content-header\\",id:\\"the-idea-markdown-first-design-flexible-resumes\\",children:[(0,r.jsx)(e.a,{href:\\"#the-idea-markdown-first-design-flexible-resumes\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(e.span,{className:\\"content-header-link\\",children:(0,r.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,r.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,r.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Idea: Markdown-First, Design-Flexible Resumes\\"]}),(0,r.jsx)(e.p,{children:\\"What if resumes were optimized for how people actually write them?\\"}),(0,r.jsx)(e.p,{children:\\"What if, instead of complex form-based editors, we created a resume builder that:\\"}),(0,r.jsxs)(e.ul,{children:[(0,r.jsx)(e.li,{children:\\"Lets you write in markdown \\\\u2014 the simplest, most natural way to write.\\"}),(0,r.jsx)(e.li,{children:\\"Shows real-time preview as you type.\\"}),(0,r.jsx)(e.li,{children:\\"Offers 10+ professional templates that you can switch instantly.\\"}),(0,r.jsx)(e.li,{children:\\"Allows complete design customization \\\\u2014 colors, fonts, spacing, layout.\\"}),(0,r.jsx)(e.li,{children:\\"Generates high-quality PDFs when you\'re ready.\\"}),(0,r.jsx)(e.li,{children:\\"Works fast, works offline, and requires no backend.\\"}),(0,r.jsx)(e.li,{children:\\"Supports profile pictures with customizable size and position.\\"})]}),(0,r.jsx)(e.p,{children:\\"Job seekers, freelancers, and professionals would no longer struggle with rigid resume builders. Writing would be as simple as typing markdown. Design would be flexible and customizable. Everything would work offline, respecting privacy with zero cloud dependencies.\\"}),(0,r.jsxs)(e.p,{children:[\\"This is the core vision of \\",(0,r.jsx)(e.strong,{children:\\"Free Resume Builder\\"}),\\":\\"]}),(0,r.jsx)(e.blockquote,{children:(0,r.jsx)(e.p,{children:\\"Turning resume creation into a simple, markdown-first experience \\\\u2014 with the flexibility to customize every aspect of the design.\\"})}),(0,r.jsxs)(e.h2,{className:\\"content-header\\",id:\\"what-problem-are-we-solving\\",children:[(0,r.jsx)(e.a,{href:\\"#what-problem-are-we-solving\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(e.span,{className:\\"content-header-link\\",children:(0,r.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,r.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,r.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Problem Are We Solving?\\"]}),(0,r.jsxs)(e.ul,{children:[(0,r.jsx)(e.li,{children:\\"Complex, form-based resume builders that slow down the writing process.\\"}),(0,r.jsx)(e.li,{children:\\"Rigid templates that limit customization and personalization.\\"}),(0,r.jsx)(e.li,{children:\\"Slow, bloated interfaces that require constant internet connectivity.\\"}),(0,r.jsx)(e.li,{children:\\"Generic-looking resumes that all look the same.\\"}),(0,r.jsx)(e.li,{children:\\"Limited design control \\\\u2014 can\'t easily change colors, fonts, or spacing.\\"}),(0,r.jsx)(e.li,{children:\\"Privacy concerns with cloud-based resume services storing your data.\\"}),(0,r.jsx)(e.li,{children:\\"Over-engineered solutions that make simple resume updates a chore.\\"})]}),(0,r.jsxs)(e.h2,{className:\\"content-header\\",id:\\"how-free-resume-builder
1-solves-it\\",children:[(0,r.jsx)(e.a,{href:\\"#how-free-resume-builder-solves-it\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(e.span,{className:\\"content-header-link\\",children:(0,r.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,r.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,r.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"How Free Resume Builder Solves It\\"]}),(0,r.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,r.jsx)(e.strong,{children:\\"Markdown-Based Editing\\"}),\\":\\",(0,r.jsx)(e.br,{}),\\"Write your resume in markdown with slash commands for quick formatting. No complex forms, no rigid structure \\\\u2014 just write naturally and see it formatted instantly.\\"]}),(0,r.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,r.jsx)(e.strong,{children:\\"10 Professional Templates\\"}),\\":\\",(0,r.jsx)(e.br,{}),\\"Choose from Standard, Modern, Minimalist, Professional, Elegant, Creative, Tech, Clean, Classic, and Serif templates. Switch between templates instantly to find the perfect look.\\"]}),(0,r.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,r.jsx)(e.strong,{children:\\"Real-Time Preview\\"}),\\":\\",(0,r.jsx)(e.br,{}),\\"See your changes instantly as you type. No waiting, no refresh \\\\u2014 just write and watch your resume come to life in real-time.\\"]}),(0,r.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,r.jsx)(e.strong,{children:\\"Complete Design Customization\\"}),\\":\\",(0,r.jsx)(e.br,{}),\\"Customize colors, fonts, spacing, layout, title alignment, and more. Full control over every aspect of your resume\'s appearance.\\"]}),(0,r.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,r.jsx)(e.strong,{children:\\"High-Quality PDF Export\\"}),\\":\\",(0,r.jsx)(e.br,{}),\\"Download your resume as a high-quality PDF when you\'re ready. Perfect for job applications, LinkedIn, or printing.\\"]}),(0,r.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,r.jsx)(e.strong,{children:\\"Import/Export Markdown\\"}),\\":\\",(0,r.jsx)(e.br,{}),\\"Import existing markdown files or export your resume as markdown. Your resume data stays portable and under your control.\\"]}),(0,r.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,r.jsx)(e.strong,{children:\\"Responsive Design\\"}),\\":\\",(0,r.jsx)(e.br,{}),\\"Works seamlessly on desktop and mobile devices. Edit your resume from anywhere, on any device.\\"]}),(0,r.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,r.jsx)(e.strong,{children:\\"Picture Support\\"}),\\":\\",(0,r.jsx)(e.br,{}),\\"Add profile pictures with customizable size, position, and style. Make your resume stand out with a professional photo.\\"]}),(0,r.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,r.jsx)(e.strong,{children:\\"Fast & Lightweight\\"}),\\":\\",(0,r.jsx)(e.br,{}),\\"Built with Next.js for optimal performance. Fast loading, smooth editing, and instant preview updates.\\"]}),(0,r.jsxs)(e.p,{children:[\\"\\\\u2705 \\",(0,r.jsx)(e.strong,{children:\\"100% Offline & Privacy-First\\"}),\\":\\",(0,r.jsx)(e.br,{}),\\"Works completely offline with no backend required. Your resume data stays in your browser. No cloud sync, no tracking, no data leaving your device.\\"]}),(0,r.jsxs)(e.h2,{className:\\"content-header\\",id:\\"the-future-simple-fast-customizable-resumes\\",children:[(0,r.jsx)(e.a,{href:\\"#the-future-simple-fast-customizable-resumes\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(e.span,{className:\\"content-header-link\\",children:(0,r.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,r.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,r.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Future: Simple, Fast, Customizable Resumes\\"]}),(0,r.jsxs)(e.p,{children:[\\"With \\",(0,r.jsx)(e.strong,{children:\\"Free Resume Builder\\"}),\\", creating and updating resumes is as simple as writing markdown and customizing the design. No complex forms. No rigid templates. No privacy concerns. Just fast, flexible resume creation that works everywhere.\\"]}),(0,r.jsx)(e.p,{children:\\"This is more than a tool.\\"}),(0,r.jsx)(e.blockquote,{children:(0,r.jsx)(e.p,{children:\\"It\'s the future of resume creation \\\\u2014 markdown-first, design-flexible, privacy-respecting.\\"})})]})}function h(i={}){let{wrapper:e}=i.components||{};return e?(0,r.jsx)(e,{...i,children:(0,r.jsx)(c,{...i})}):c(i)}function x(i,e){throw new Error(\\"Expected \\"+(e?\\"component\\":\\"object\\")+\\" `\\"+i+\\"` to be defined: you likely forgot to import, pass, or provide it.\\")}return v(M);})();\\n;return Component;"},"_id":"blog/free-resume-builder.mdx","_raw":{"sourceFilePath":"blog/free-resume-builder.mdx","sourceFileName":"free-resume-builder.mdx","sourceFileDir":"blog","contentType":"mdx","flattenedPath":"blog/free-resume-builder"},"type":"Blog","readingTime":{"text":"4 min read","minutes":3.48,"time":208800,"words":696},"slug":"free-resume-builder","path":"blog/free-resume-builder","filePath":"blog/free-resume-builder.mdx","toc":[{"value":"The Spark: The Complexity of Modern Resume Building","url":"#the-spark-the-complexity-of-modern-resume-building","depth":1},{"value":"The Idea: Markdown-First, Design-Flexible Resumes","url":"#the-idea-markdown-first-design-flexible-resumes","depth":2},{"value":"What Problem Are We Solving?","url":"#what-problem-are-we-solving-3","depth":2},{"value":"How Free Resume Builder Solves It","url":"#how-free-resume-builder
1-solves-it","depth":2},{"value":"The Future: Simple, Fast, Customizable Resumes","url":"#the-future-simple-fast-customizable-resumes","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"Free Resume Builder â Markdown-Based Professional Resume Creator","datePublished":"2025-01-15T00:00:00.000Z","dateModified":"2025-01-15T00:00:00.000Z","description":"Free Resume Builder, a modern, markdown-based resume creator built with Next.js. Create professional resumes with real-time preview, 10+ templates, and PDF export capabilities â all in your browser.","url":"https://www.devity.in/blog/free-resume-builder/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/resume.devity.in-screenshot.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"Kairo â An Intelligent Break Reminder That Knows When You Actually Need One","date":"2026-05-22T00:00:00.000Z","tags":["macOS App","Health","Productivity","SwiftUI","Break Reminder","devity-engineering"],"keywords":[],"lastmod":"2026-05-22T00:00:00.000Z","draft":false,"summary":"Kairo is a macOS menu bar app that intelligently forces you to take breaks. It watches your work patterns, respects your meetings, credits natural idle time, and steps in when you have been at the screen too long â no manual timers, no guesswork.","images":"/static/images/kairo-screenshot.png","layout":"PostLayout","canonicalUrl":"","faqs":[],"body":{"raw":"\\n# The Spark: You Forgot to Stand Up Again\\n\\nThree hours pass. Your back aches. Your eyes are dry. You glance at the clock and realize you skipped lunch â again.\\n\\nEvery knowledge worker knows this feeling. You sit down with good intentions, get absorbed in a problem, and surface hours later wondering where the time went. The irony is sharp: the better you focus, the worse you treat your body.\\n\\nBreak reminder apps exist, of course. Most of them are timers. They ring every 30 minutes whether you are mid-sentence in a critical email or walking back from the kitchen. They don\'t know if you just returned from a five-minute stretch. They don\'t care that your standup starts in t
1wo minutes. They interrupt without intelligence, and eventually, you disable them.\\n\\nThat is where **Kairo** comes in.\\n\\n## The Idea: Breaks at the Right Time\\n\\nWhat if a break reminder actually understood when you were working â and when you were not?\\n\\nWhat if it watched your keyboard and mouse activity, checked your calendar, noticed when you walked away naturally, and only intervened when you genuinely needed to stop?\\n\\n- If you have been idle for five minutes, that counts as a break. The timer resets.\\n- If a meeting starts in ten minutes, the break waits until after.\\n- If you skip a break, the next one is mandatory and a little longer.\\n- If you have been working for 90 minutes straight without any real pause, the app steps in regardless.\\n\\nNo manual timers. No guesswork. The app does the thinking so you can focus on your work.\\n\\nThis is the core vision of **Kairo**:\\n\\n> A macOS menu bar app that intelligently forces you to take breaks â respecting your calendar, rewarding natural pauses, and stepping in when you have been at the screen too long.\\n\\n## What Problem Are We Solving?\\n\\n- Forgetting to take breaks during deep focus sessions.\\n- Dumb timers that interrupt you at the worst possible moment.\\n- Break reminders that fire right before a meeting starts.\\n- No credit for natural breaks â walking to the kitchen, chatting with a colleague, stepping outside.\\n- Skipping a break with zero consequences, making it easy to never break at all.\\n- Apps that require constant manual interaction to stay useful.\\n\\n## How Kairo Solves It\\n\\n**Idle-Aware Focus Tracking**:\\nKairo uses system idle time detection to know when you are actually at your desk. If your keyboard and mouse have been quiet for 20 seconds, the focus timer pauses. If you walk away for three minutes, you start earning break credit. Five minutes away? Your focus timer resets entirely. A genuine break is a genuine break â the app does not punish you for stepping away.\\n\\n**Calendar-Aware Scheduling**:\\nConnect your calendar and Kairo checks for upcoming meetings. If a break would land within ten minutes of a meeting, it delays automatically. When the meeting ends, the break triggers. You never get pulled away from your screen right before a call starts.\\n\\n**Progressive Enforcement**:\\nIn flexible mode, breaks are suggestions. You can skip one. But skip it, and the next break becomes mandatory â slightly longer, and you cannot skip it. This recovery lock ensures that skipping once does not become skipping always. In strict mode, every break is mandatory from the start.\\n\\n**Continuous Work Safety Net**:\\nRegardless of settings, if you hit 90 minutes of continuous work without any meaningful pause, Kairo triggers a mandatory break. This is the hard ceiling â a safety net for the days when you are too deep in the zone to notice time passing.\\n\\n**Full-Screen Mandatory Breaks**:\\nWhen a break is mandatory, Kairo takes over the screen. Dock hidden, menu bar gone, process switching disabled. A calm countdown tells you how long to stay away. This is not a notification you can swipe away â it is a break you have to take.\\n\\n**Floating Panel for Soft Breaks**:\\nNon-mandatory breaks show a floating panel in the corner of your screen with a countdown timer and activity suggestions â \\"Hydrate with a glass of water,\\" \\"Stretch your body,\\" \\"Walk for a few minutes.\\" Visible enough to act on, gentle enough not to break your train of thought if you genuinely need another minute.\\n\\n## How It Works\\n\\n### The Focus Cycle\\n\\nWhen you start working, Kairo watches:\\n\\n- Every second, it checks system idle time via IOKit.\\n- If you are active (idle < 20 seconds), the focus timer increments.\\n- When the focus timer hits your configured threshold (default: 30 minutes), a break triggers.\\n- The break lasts five minutes (configurable), then the cycle resets.\\n\\n### Natural Break Credit\\n\\nNot every break needs to be forced:\\n\\n- **3+ minutes idle** â Partial credit. Your focus timer decreases proportionally.\\n- **5+ minutes idle** â Full reset. You took a real break, and Kairo recognizes it.\\n- **Continuous work counter** also resets, so the 90-minute safety net adjusts too.\\n\\n### Meeting Awareness\\n\\nIf you connect your calendar:\\n\\n- Kairo fetches your next event and checks whether it starts within ten minutes.\\n- If a break would collide with a meeting, it is delayed â not skipped.\\n- The dashboard shows \\"Break delayed â meeting starting soon.\\"\\n- When the meeting ends, the break fires automatically.\\n\\n### The Skip-Recovery System\\n\\nIn flexible mode:\\n\\
1n1. A break triggers. You see a floating panel.\\n2. You can skip it â once.\\n3. Skipping activates a recovery lock: the next break is mandatory, three minutes longer, and cannot be skipped.\\n4. Complete that mandatory break, and the lock releases. The cycle returns to normal.\\n\\nThis creates a natural rhythm: skip occasionally when you need to, but never indefinitely.\\n\\n## What Makes It Different\\n\\n**1. It Knows When You Are Working**\\nMost break reminders use a fixed timer. Kairo tracks actual activity. Walk away for five minutes and come back â your timer reflects that. No phantom breaks, no wasted interruptions.\\n\\n**2. It Respects Your Calendar**\\nA break two minutes before a standup is worse than no break at all. Kairo checks your calendar and waits. When the meeting ends, the break fires. Simple, but no other break app does this.\\n\\n**3. Skipping Has Consequences**\\nSkip a break, and the next one is longer and mandatory. This single rule transforms the experience: you skip when you genuinely need to, not out of habit.\\n\\n**4. It Actually Forces You to Stop**\\nMandatory breaks take over the screen. No switching to another app, no dismissing a notification. You sit with the countdown and step away. This is the feature that makes Kairo work where others fail.\\n\\n**5. Natural Breaks Count**\\nThe idle detection is not just for pausing the timer â it actively credits you. Three minutes away earns partial credit. Five minutes resets the cycle. The app rewards healthy behavior instead of ignoring it.\\n\\n## Key Features\\n\\n### Intelligent Break Timing\\n\\n- **Idle-Aware Tracking** â Knows when you are working vs. away from the screen.\\n- **Calendar Integration** â Delays breaks to avoid interrupting meetings.\\n- **Natural Break Credit** â Idle time of 3-5 minutes partially or fully resets the focus timer.\\n- **90-Minute Safety Net** â Mandatory break after sustained continuous work.\\n\\n### Progressive Enforcement\\n\\n- **Flexible Mode** â Breaks are suggestions you can skip once.\\n- **Strict Mode** â Every break is mandatory from the start.\\n- **Recovery Lock** â Skip a break and the next one cannot be skipped.\\n- **Full-Screen Overlay** â Mandatory breaks take over the screen completely.\\n\\n### Menu Bar & Dashboard\\n\\n- **Live Countdown** â See time until next break in the menu bar.\\n- **Progress Ring** â Visual indicator showing how close you are to the next break.\\n- **Activity Suggestions** â Rotating tips during breaks: hydrate, stretch, walk.\\n- **Floating Break Panel** â Non-mandatory breaks show a gentle countdown in the corner.\\n\\n### Set It and Forget It\\n\\n- **Launch at Login** â Starts automatically so you never forget to turn it on.\\n- **Persistent Settings** â Mode, break period, and break duration survive restarts.\\n- **Zero Configuration Needed** â Works with sensible defaults out of the box.\\n- **Notification Support** â Break alerts even when the app is in the background.\\n\\n## The Experience\\n\\n**Menu Bar First** â Kairo lives in your menu bar. A single icon shows the status. Click it for a quick view: countdown, state, current app, and controls. Open the dashboard only when you want details.\\n\\n**Dark, Calm Interface** â The dashboard and break overlays use a dark gradient palette designed not to jar you when a break triggers. Warm amber countdown text, soft greens for activity suggestions, muted backgrounds. It is a break, not an alarm.\\n\\n**One-Click Controls** â Start a break manually, pause tracking for 15 minutes, toggle between flexible and strict mode, skip a soft break. Everything is one click from the menu bar.\\n\\n## Perfect For\\n\\n- Developers and designers who lose hours in deep focus.\\n- Remote workers without natural break triggers like commutes or lunch calls.\\n- Writers and researchers who sit for long stretches without noticing.\\n- Anyone who has said \\"I should take more breaks\\" and never followed through.\\n\\n## Kairo vs Simple Break Timers\\n\\n| Feature | Kairo | Simple Break Timer |\\n| -------------------- | ------------------------------ | -------------------------- |\\n| **Timing** | Activity-aware | Fixed interval |\\n| **Calendar** | Delays around meetings | No awareness |\\n| **Idle Credit** | Natural breaks count | Timer runs regardless |\\n| **Enforcement** | Full-screen mandatory overlay | Dismissible notification |\\n| **Skip Handling** | Next break becomes mandatory | Skip freely, forever |\\n| **Suggestions** | Rotating activity tips | None |\\n| **Persistence** | Settings survive restarts | Often resets |\\n| **Setup** | Launch at login, zero config | Manual start each day |\\n\\n## Download\\n\\
1nKairo is free and open source. Download the latest release for macOS:\\n\\n[**Download Kairo v1.0.0**](https://github.com/devity-in/kairo/releases/tag/v1.0.0)\\n\\n1. Download `Kairo-v1.0.0-macOS.zip` from the release page.\\n2. Unzip and drag `kairo.app` to your Applications folder.\\n3. Launch Kairo â it appears in your menu bar.\\n4. Grant Accessibility permission when prompted â so Kairo can detect idle time.\\n5. Connect your calendar (optional) â so breaks respect your meetings.\\n6. Enable notifications â so you get alerted even when backgrounded.\\n7. Work normally â Kairo handles the rest.\\n\\n## Your Settings\\n\\n- **Break Period** â How long you work before a break (default: 30 minutes).\\n- **Break Duration** â How long each break lasts (default: 5 minutes).\\n- **Mode** â Flexible (can skip once) or Strict (every break mandatory).\\n- **Launch at Login** â Toggle in the setup panel.\\n\\nAll settings persist across app restarts. Change them once and forget about it.\\n\\n## The Future: Work Hard, Break Smart\\n\\nWith **Kairo**, you do not have to remember to take breaks. You do not have to set timers, watch the clock, or feel guilty about skipping. The app watches your patterns, respects your schedule, credits your natural pauses, and steps in when you need it most.\\n\\nIt is not about working less. It is about working sustainably.\\n\\n> Kairo is where focus meets recovery â an intelligent break system that gets the timing right so you can keep doing your best work.\\n","code":"var Component=(()=>{var u=Object.create;var i=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var p=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var k=(n,a)=>()=>(a||n((a={exports:{}}
1).exports,a),a.exports),y=(n,a)=>{for(var r in a)i(n,r,{get:a[r],enumerable:!0})},o=(n,a,r,l)=>{if(a&&typeof a==\\"object\\"||typeof a==\\"function\\")for(let t of m(a))!w.call(n,t)&&t!==r&&i(n,t,{get:()=>a[t],enumerable:!(l=g(a,t))||l.enumerable});return n};var f=(n,a,r)=>(r=n!=null?u(p(n)):{},o(a||!n||!n.__esModule?i(r,\\"default\\",{value:n,enumerable:!0}):r,n)),b=n=>o(i({},\\"__esModule\\",{value:!0}),n);var h=k((M,s)=>{s.exports=_jsx_runtime});var x={};y(x,{default:()=>c,frontmatter:()=>v});var e=f(h()),v={title:\\"Kairo \\\\u2014 An Intelligent Break Reminder That Knows When You Actually Need One\\",date:\\"2026-05-22\\",lastmod:\\"2026-05-22\\",tags:[\\"macOS App\\",\\"Health\\",\\"Productivity\\",\\"SwiftUI\\",\\"Break Reminder\\",\\"devity-engineering\\"],draft:!1,images:\\"/static/images/kairo-screenshot.png\\",summary:\\"Kairo is a macOS menu bar app that intelligently forces you to take breaks. It watches your work patterns, respects your meetings, credits natural idle time, and steps in when you have been at the screen too long \\\\u2014 no manual timers, no guesswork.\\",layout:\\"PostLayout\\",canonicalUrl:\\"\\"};function d(n){let a={a:\\"a\\",blockquote:\\"blockquote\\",code:\\"code\\",h1:\\"h1\\",h2:\\"h2\\",h3:\\"h3\\",li:\\"li\\",ol:\\"ol\\",p:\\"p\\",path:\\"path\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",table:\\"table\\",tbody:\\"tbody\\",td:\\"td\\",th:\\"th\\",thead:\\"thead\\",tr:\\"tr\\",ul:\\"ul\\",...n.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsxs)(a.h1,{className:\\"content-header\\",id:\\"the-spark-you-forgot-to-stand-up-again\\",children:[(0,e.jsx)(a.a,{href:\\"#the-spark-you-forgot-to-stand-up-again\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Spark: You Forgot to Stand Up Again\\"]}),(0,e.jsx)(a.p,{children:\\"Three hours pass. Your back aches. Your eyes are dry. You glance at the clock and realize you skipped lunch \\\\u2014 again.\\"}),(0,e.jsx)(a.p,{children:\\"Every knowledge worker knows this feeling. You sit down with good intentions, get absorbed in a problem, and surface hours later wondering where the time went. The irony is sharp: the better you focus, the worse you treat your body.\\"}),(0,e.jsx)(a.p,{children:\\"Break reminder apps exist, of course. Most of them are timers. They ring every 30 minutes whether you are mid-sentence in a critical email or walking back from the kitchen. They don\'t know if you just returned from a five-minute stretch. They don\'t care that your standup starts in t
1wo minutes. They interrupt without intelligence, and eventually, you disable them.\\"}),(0,e.jsxs)(a.p,{children:[\\"That is where \\",(0,e.jsx)(a.strong,{children:\\"Kairo\\"}),\\" comes in.\\"]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"the-idea-breaks-at-the-right-time\\",children:[(0,e.jsx)(a.a,{href:\\"#the-idea-breaks-at-the-right-time\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Idea: Breaks at the Right Time\\"]}),(0,e.jsx)(a.p,{children:\\"What if a break reminder actually understood when you were working \\\\u2014 and when you were not?\\"}),(0,e.jsx)(a.p,{children:\\"What if it watched your keyboard and mouse activity, checked your calendar, noticed when you walked away naturally, and only intervened when you genuinely needed to stop?\\"}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:\\"If you have been idle for five minutes, that counts as a break. The timer resets.\\"}),(0,e.jsx)(a.li,{children:\\"If a meeting starts in ten minutes, the break waits until after.\\"}),(0,e.jsx)(a.li,{children:\\"If you skip a break, the next one is mandatory and a little longer.\\"}),(0,e.jsx)(a.li,{children:\\"If you have been working for 90 minutes straight without any real pause, the app steps in regardless.\\"})]}),(0,e.jsx)(a.p,{children:\\"No manual timers. No guesswork. The app does the thinking so you can focus on your work.\\"}),(0,e.jsxs)(a.p,{children:[\\"This is the core vision of \\",(0,e.jsx)(a.strong,{children:\\"Kairo\\"}),\\":\\"]}),(0,e.jsx)(a.blockquote,{children:(0,e.jsx)(a.p,{children:\\"A macOS menu bar app that intelligently forces you to take breaks \\\\u2014 respecting your calendar, rewarding natural pauses, and stepping in when you have been at the screen too long.\\"})}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"what-problem-are-we-solving\\",children:[(0,e.jsx)(a.a,{href:\\"#what-problem-are-we-solving\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Problem Are We Solving?\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:\\"Forgetting to take breaks during deep focus sessions.\\"}),(0,e.jsx)(a.li,{children:\\"Dumb timers that interrupt you at the worst possible moment.\\"}),(0,e.jsx)(a.li,{children:\\"Break reminders that fire right before a meeting starts.\\"}),(0,e.jsx)(a.li,{children:\\"No credit for natural breaks \\\\u2014 walking to the kitchen, chatting with a colleague, stepping outside.\\"}),(0,e.jsx)(a.li,{children:\\"Skipping a break with zero consequences, making it easy to never break at all.\\"}),(0,e.jsx)(a.li,{children:\\"Apps that require constant manual interaction to stay useful.\\"})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"how-kairo-solves-it\\",children:[(0,e.jsx)(a.a,{href:\\"#how-kairo-solves-it\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"How Kairo Solves It\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"Idle-Aware Focus Tracking\\"}),\\": Kairo uses system idle time detection to know when you are actually at your desk. If your keyboard and mouse have been quiet for 20 seconds, the focus timer pauses. If you walk away for three minutes, you start earning break credit. Five minutes away? Your focus timer resets entirely. A genuine break is a genuine break \\\\u2014 the app does not punish you for stepping away.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"Calendar-Aware Scheduling\\"}),\\": Connect your calendar and Kairo checks for upcoming meetings. If a break would land within ten minutes of a meeting, it delays automatically. When the meeting ends, the break triggers. You never get pulled away from your screen right before a call starts.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"Progressive Enforcement\\"}),\\": In flexible mode, breaks are suggestions. You can skip one. But skip it, and the next break becomes mandatory \\\\u2014 slightly longer, and you cannot skip it. This recovery lock ensures that skipping once does not become skipping always. In strict mode, every break is mandatory from the start.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"Continuous Work Safety Net\\"}),\\": Regardless of settings, if you hit 90 minutes of continuous work without any meaningful pause, Kairo triggers a mandatory break. This is the hard ceiling \\\\u2014 a safety net for the days when you are too deep in the zone to notice time passing.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"Full-Screen Mandatory Breaks\\"}),\\": When a break is mandatory, Kairo takes over the screen. Dock hidden, menu bar gone, process switching disabled. A calm countdown tells you how long to stay away. This is not a notification you can swipe away \\\\u2014 it is a break you have to take.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"Floating Panel for Soft Breaks\\"}),\': Non-mandatory breaks show a floating panel in the corner of your screen with a countdown timer and activity suggestions \\\\u2014 \\"Hydrate with a glass of water,\\" \\"Stretch
1your body,\\" \\"Walk for a few minutes.\\" Visible enough to act on, gentle enough not to break your train of thought if you genuinely need another minute.\']}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"how-it-works\\",children:[(0,e.jsx)(a.a,{href:\\"#how-it-works\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"How It Works\\"]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"the-focus-cycle\\",children:[(0,e.jsx)(a.a,{href:\\"#the-focus-cycle\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Focus Cycle\\"]}),(0,e.jsx)(a.p,{children:\\"When you start working, Kairo watches:\\"}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:\\"Every second, it checks system idle time via IOKit.\\"}),(0,e.jsx)(a.li,{children:\\"If you are active (idle < 20 seconds), the focus timer increments.\\"}),(0,e.jsx)(a.li,{children:\\"When the focus timer hits your configured threshold (default: 30 minutes), a break triggers.\\"}),(0,e.jsx)(a.li,{children:\\"The break lasts five minutes (configurable), then the cycle resets.\\"})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"natural-break-credit\\",children:[(0,e.jsx)(a.a,{href:\\"#natural-break-credit\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Natural Break Credit\\"]}),(0,e.jsx)(a.p,{children:\\"Not every break needs to be forced:\\"}),(0,e.jsxs)(a.ul,{children:[(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"3+ minutes idle\\"}),\\" \\\\u2014 Partial credit. Your focus timer decreases proportionally.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"5+ minutes idle\\"}),\\" \\\\u2014 Full reset. You took a real break, and Kairo recognizes it.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Continuous work counter\\"}),\\" also resets, so the 90-minute safety net adjusts too.\\"]})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"meeting-awareness\\",children:[(0,e.jsx)(a.a,{href:\\"#meeting-awareness\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Meeting Awareness\\"]}),(0,e.jsx)(a.p,{children:\\"If you connect your calendar:\\"}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:\\"Kairo fetches your next event and checks whether it starts within ten minutes.\\"}),(0,e.jsx)(a.li,{children:\\"If a break would collide with a meeting, it is delayed \\\\u2014 not skipped.\\"}),(0,e.jsx)(a.li,{children:\'The dashboard shows \\"Break delayed \\\\u2014 meeting starting soon.\\"\'}),(0,e.jsx)(a.li,{children:\\"When the meeting ends, the break fires automatically.\\"})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"the-skip-recovery-system\\",children:[(0,e.jsx)(a.a,{href:\\"#the-skip-recovery-system\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Skip-Recovery System\\"]}),(0,e.jsx)(a.p,{children:\\"In flexible mode:\\"}),(0,e.jsxs)(a.ol,{children:[(0,e.jsx)(a.li,{children:\\"A break triggers. You see a floating panel.\\"}),(0,e.jsx)(a.li,{children:\\"You can skip it \\\\u2014 once.\\"}),(0,e.jsx)(a.li,{children:\\"Skipping activates a recovery lock: the next break is mandatory, three minutes longer, and cannot be skipped.\\"}),(0,e.jsx)(a.li,{children:\\"Complete that mandatory break, and the lock releases. The cycle returns to normal.\\"})]}),(0,e.jsx)(a.p,{children:\\"This creates a natural rhythm: skip occasionally when you need to, but never indefinitely.\\"}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"what-makes-it-different\\",children:[(0,e.jsx)(a.a,{href:\\"#what-makes-it-different\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Makes It Different\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"1. It Knows When You Are Working\\"}),\\" Most break reminders use a fixed timer. Kairo tracks actual activity. Walk away for five minutes and come back \\\\u2014 your timer reflects that. No phantom breaks, no wasted interruptions.\\"]}
1),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"2. It Respects Your Calendar\\"}),\\" A break two minutes before a standup is worse than no break at all. Kairo checks your calendar and waits. When the meeting ends, the break fires. Simple, but no other break app does this.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"3. Skipping Has Consequences\\"}),\\" Skip a break, and the next one is longer and mandatory. This single rule transforms the experience: you skip when you genuinely need to, not out of habit.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"4. It Actually Forces You to Stop\\"}),\\" Mandatory breaks take over the screen. No switching to another app, no dismissing a notification. You sit with the countdown and step away. This is the feature that makes Kairo work where others fail.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"5. Natural Breaks Count\\"}),\\" The idle detection is not just for pausing the timer \\\\u2014 it actively credits you. Three minutes away earns partial credit. Five minutes resets the cycle. The app rewards healthy behavior instead of ignoring it.\\"]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"key-features\\",children:[(0,e.jsx)(a.a,{href:\\"#key-features\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Key Features\\"]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"intelligent-break-timing\\",children:[(0,e.jsx)(a.a,{href:\\"#intelligent-break-timing\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Intelligent Break Timing\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Idle-Aware Tracking\\"}),\\" \\\\u2014 Knows when you are working vs. away from the screen.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Calendar Integration\\"}),\\" \\\\u2014 Delays breaks to avoid interrupting meetings.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Natural Break Credit\\"}),\\" \\\\u2014 Idle time of 3-5 minutes partially or fully resets the focus timer.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"90-Minute Safety Net\\"}),\\" \\\\u2014 Mandatory break after sustained continuous work.\\"]})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"progressive-enforcement\\",children:[(0,e.jsx)(a.a,{href:\\"#progressive-enforcement\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Progressive Enforcement\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Flexible Mode\\"}),\\" \\\\u2014 Breaks are suggestions you can skip once.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Strict Mode\\"}),\\" \\\\u2014 Every break is mandatory from the start.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Recovery Lock\\"}),\\" \\\\u2014 Skip a break and the next one cannot be skipped.\\"]}
1),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Full-Screen Overlay\\"}),\\" \\\\u2014 Mandatory breaks take over the screen completely.\\"]})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"menu-bar--dashboard\\",children:[(0,e.jsx)(a.a,{href:\\"#menu-bar--dashboard\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Menu Bar & Dashboard\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Live Countdown\\"}),\\" \\\\u2014 See time until next break in the menu bar.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Progress Ring\\"}),\\" \\\\u2014 Visual indicator showing how close you are to the next break.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Activity Suggestions\\"}),\\" \\\\u2014 Rotating tips during breaks: hydrate, stretch, walk.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Floating Break Panel\\"}),\\" \\\\u2014 Non-mandatory breaks show a gentle countdown in the corner.\\"]})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"set-it-and-forget-it\\",children:[(0,e.jsx)(a.a,{href:\\"#set-it-and-forget-it\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Set It and Forget It\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Launch at Login\\"}),\\" \\\\u2014 Starts automatically so you never forget to turn it on.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Persistent Settings\\"}),\\" \\\\u2014 Mode, break period, and break duration survive restarts.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Zero Configuration Needed\\"}),\\" \\\\u2014 Works with sensible defaults out of the box.\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Notification Support\\"}),\\" \\\\u2014 Break alerts even when the app is in the background.\\"]})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"the-experience\\",children:[(0,e.jsx)(a.a,{href:\\"#the-experience\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Experience\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"Menu Bar First\\"}),\\" \\\\u2014 Kairo lives in your menu bar. A single icon shows the status. Click it for a quick view: countdown, state, current app, and controls. Open the dashboard only when you want details.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"Dark, Calm Interface\\"}
1),\\" \\\\u2014 The dashboard and break overlays use a dark gradient palette designed not to jar you when a break triggers. Warm amber countdown text, soft greens for activity suggestions, muted backgrounds. It is a break, not an alarm.\\"]}),(0,e.jsxs)(a.p,{children:[(0,e.jsx)(a.strong,{children:\\"One-Click Controls\\"}),\\" \\\\u2014 Start a break manually, pause tracking for 15 minutes, toggle between flexible and strict mode, skip a soft break. Everything is one click from the menu bar.\\"]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"perfect-for\\",children:[(0,e.jsx)(a.a,{href:\\"#perfect-for\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Perfect For\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:\\"Developers and designers who lose hours in deep focus.\\"}),(0,e.jsx)(a.li,{children:\\"Remote workers without natural break triggers like commutes or lunch calls.\\"}),(0,e.jsx)(a.li,{children:\\"Writers and researchers who sit for long stretches without noticing.\\"}),(0,e.jsx)(a.li,{children:\'Anyone who has said \\"I should take more breaks\\" and never followed through.\'})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"kairo-vs-simple-break-timers\\",children:[(0,e.jsx)(a.a,{href:\\"#kairo-vs-simple-break-timers\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Kairo vs Simple Break Timers\\"]}),(0,e.jsxs)(a.table,{children:[(0,e.jsx)(a.thead,{children:(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.th,{children:\\"Feature\\"}),(0,e.jsx)(a.th,{children:\\"Kairo\\"}),(0,e.jsx)(a.th,{children:\\"Simple Break Timer\\"})]})}),(0,e.jsxs)(a.tbody,{children:[(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Timing\\"})}),(0,e.jsx)(a.td,{children:\\"Activity-aware\\"}),(0,e.jsx)(a.td,{children:\\"Fixed interval\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Calendar\\"})}),(0,e.jsx)(a.td,{children:\\"Delays around meetings\\"}),(0,e.jsx)(a.td,{children:\\"No awareness\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Idle Credit\\"})}),(0,e.jsx)(a.td,{children:\\"Natural breaks count\\"}),(0,e.jsx)(a.td,{children:\\"Timer runs regardless\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Enforcement\\"})}),(0,e.jsx)(a.td,{children:\\"Full-screen mandatory overlay\\"}),(0,e.jsx)(a.td,{children:\\"Dismissible notification\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Skip Handling\\"})}),(0,e.jsx)(a.td,{children:\\"Next break becomes mandatory\\"}),(0,e.jsx)(a.td,{children:\\"Skip freely, forever\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Suggestions\\"})}),(0,e.jsx)(a.td,{children:\\"Rotating activity tips\\"}),(0,e.jsx)(a.td,{children:\\"None\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Persistence\\"})}),(0,e.jsx)(a.td,{children:\\"Settings survive restarts\\"}),(0,e.jsx)(a.td,{children:\\"Often resets\\"})]}),(0,e.jsxs)(a.tr,{children:[(0,e.jsx)(a.td,{children:(0,e.jsx)(a.strong,{children:\\"Setup\\"})}),(0,e.jsx)(a.td,{children:\\"Launch at login, zero config\\"}),(0,e.jsx)(a.td,{children:\\"Manual start each day\\"})]})]})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"download\\",children:[(0,e.jsx)(a.a,{href:\\"#download\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Download\\"]}),(0,e.jsx)(a.p,{children:\\"Kairo is free and open source. Download the latest release for macOS:\\"}),(0,e.jsx)(a.p,{children:(0,e.jsx)(a.a,{href:\\"https://github.com/devity-in/kairo/releases/tag/v1.0.0\\",children:(0,e.jsx)(a.strong,{children:\\"Download Kairo v1.0.0\\"})})}),(0,e.jsxs)(a.ol,{children:[(0,e.jsxs)(a.li,{children:[\\"Download \\",(0,e.jsx)(a.code,{children:\\"Kairo-v1.0.0-macOS.zip\\"}),\\" from the release page.\\"]}),(0,e.jsxs)(a.li,{children:[\\"Unzip and drag \\",(0,e.jsx)(a.code,{children:\\"kairo.app\\"}
1),\\" to your Applications folder.\\"]}),(0,e.jsx)(a.li,{children:\\"Launch Kairo \\\\u2014 it appears in your menu bar.\\"}),(0,e.jsx)(a.li,{children:\\"Grant Accessibility permission when prompted \\\\u2014 so Kairo can detect idle time.\\"}),(0,e.jsx)(a.li,{children:\\"Connect your calendar (optional) \\\\u2014 so breaks respect your meetings.\\"}),(0,e.jsx)(a.li,{children:\\"Enable notifications \\\\u2014 so you get alerted even when backgrounded.\\"}),(0,e.jsx)(a.li,{children:\\"Work normally \\\\u2014 Kairo handles the rest.\\"})]}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"your-settings\\",children:[(0,e.jsx)(a.a,{href:\\"#your-settings\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Your Settings\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Break Period\\"}),\\" \\\\u2014 How long you work before a break (default: 30 minutes).\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Break Duration\\"}),\\" \\\\u2014 How long each break lasts (default: 5 minutes).\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Mode\\"}),\\" \\\\u2014 Flexible (can skip once) or Strict (every break mandatory).\\"]}),(0,e.jsxs)(a.li,{children:[(0,e.jsx)(a.strong,{children:\\"Launch at Login\\"}),\\" \\\\u2014 Toggle in the setup panel.\\"]})]}),(0,e.jsx)(a.p,{children:\\"All settings persist across app restarts. Change them once and forget about it.\\"}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"the-future-work-hard-break-smart\\",children:[(0,e.jsx)(a.a,{href:\\"#the-future-work-hard-break-smart\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Future: Work Hard, Break Smart\\"]}),(0,e.jsxs)(a.p,{children:[\\"With \\",(0,e.jsx)(a.strong,{children:\\"Kairo\\"}),\\", you do not have to remember to take breaks. You do not have to set timers, watch the clock, or feel guilty about skipping. The app watches your patterns, respects your schedule, credits your natural pauses, and steps in when you need it most.\\"]}),(0,e.jsx)(a.p,{children:\\"It is not about working less. It is about working sustainably.\\"}),(0,e.jsx)(a.blockquote,{children:(0,e.jsx)(a.p,{children:\\"Kairo is where focus meets recovery \\\\u2014 an intelligent break system that gets the timing right so you can keep doing your best work.\\"})})]})}function c(n={}){let{wrapper:a}=n.components||{};return a?(0,e.jsx)(a,{...n,children:(0,e.jsx)(d,{...n})}):d(n)}return b(x);})();\\n;return Component;"},"_id":"blog/kairo-intelligent-break-reminder.mdx","_raw":{"sourceFilePath":"blog/kairo-intelligent-break-reminder.mdx","sourceFileName":"kairo-intelligent-break-reminder.mdx","sourceFileDir":"blog","contentType":"mdx","flattenedPath":"blog/kairo-intelligent-break-reminder"},"type":"Blog","readingTime":{"text":"10 min read","minutes":9.41,"time":564600,"words":1882},"slug":"kairo-intelligent-break-reminder","path":"blog/kairo-intelligent-break-reminder","filePath":"blog/kairo-intelligent-break-reminder.mdx","toc":[{"value":"The Spark: You Forgot to Stand Up Again","url":"#the-spark-you-forgot-to-stand-up-again","depth":1},{"value":"The Idea: Breaks at the Right Time","url":"#the-idea-breaks-at-the-right-time","depth":2},{"value":"What Problem Are We Solving?","url":"#what-problem-are-we-solving-4","depth":2},{"value":"How Kairo Solves It","url":"#how-kairo-solves-it","depth":2},{"value":"How It Works","url":"#how-it-works-1","depth":2},{"value":"The Focus Cycle","url":"#the-focus-cycle","depth":3},{"value":"Natural Break Credit","url":"#natural-break-credit","depth":3},{"value":"Meeting Awareness","url":"#meeting-awareness","depth":3},{"value":"The Skip-Recovery System","url":"#the-skip-recovery-system","depth":3},{"value":"What Makes It Different","url":"#what-makes-it-different-1","depth":2},{"value":"Key Features","url":"#key-features-1","depth":2},{"value":"Intelligent Break Timing","url":"#intelligent-break-timing","depth":3},{"value":"Progressive Enforcement","url":"#progressive-enforcement","depth":3},{"value":"Menu Bar & Dashboard","url":"#menu-bar--dashboard","depth":3},{"value":"Set It and Forget It","url":"#set-it-and-forget-it","depth":3},{"value":"The Experience","url":"#the-experience-1","depth":2},{"value":"Perfect For","url":"#perfect-for-1","depth":2},{"value":"Kairo vs Simple Break Timers","url":"#kairo-vs-simple-break-timers","depth":2},{"value":"Download","url":"#download","depth":2},{"value":"Your Settings","url":"#your-settings","depth":2},{"value":"The Future: Work Hard, Break Smart","url":"#the-future-work-hard-break-smart","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"Kairo â An Intelligent Break Reminder That Knows When You Actually Need One","datePublished":"2026-05-22T00:00:00.000Z","dateModified":"2026-05-22T00:00:00.000Z","description":"Kairo is a macOS menu bar app that intelligently forces you to take breaks. It watches your work patterns, respects your meetings, credits natural idle time, and steps in when you have been at the screen too long â no manual timers, no guesswork.","url":"https://www.devity.in/blog/kairo-intelligent-break-reminder/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/kairo-screenshot.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"Exploring Life Through Panchang Time: Panchanga Anveshana","date":"2026-04-17T00:00:00.000Z","tags":["Panchang","Astrology","Indian Calendar","Spiritual Tools","Vedic"],"keywords":[],"lastmod":"2026-04-17T00:00:00.000Z","draft":true,"summary":"Discover Panchanga Anveshana, a modern tool for exploring life through Panchang time. Learn how this app helps users understand auspicious times, reflect on daily patterns, and align with Vedic traditions.","images":"/static/images/pa-screenshot.png","layout":"PostLayout","canonicalUrl":"https://blog.devity.in/panchanga-anveshana-exploring-life-through-panch
1ang-time","faqs":[],"body":{"raw":"\\n# Exploring Life Through Panchang Time: Panchanga Anveshana\\n\\nIn the fast-paced world of modern living, many are turning back to ancient wisdom for guidance. Panchang, the traditional Indian astrological calendar, has been used for centuries to determine auspicious times for activities, festivals, and personal decisions. Now, with the advent of technology, tools like Panchanga Anveshana are making this ancient knowledge accessible and interactive.\\n\\n## What is Panchanga Anveshana?\\n\\nPanchanga Anveshana is a web-based application available at [pa.devity.in](https://pa.devity.in/) that allows users to explore their lives through the lens of Panchang time. \\"Panchanga\\" means \\"five limbs\\" in Sanskrit, referring to the five key elements that describe every moment: Tithi (lunar day), Nakshatra (lunar mansion), Vara (weekday), Yoga (solar-lunar angle), and Karana (half tithi).\\n\\nThe app provides today\'s Panchang at a glance, along with astronomical positions, guidance based on the current Tithi, and educational resources to help users understand these concepts.\\n\\n## Key Features\\n\\n### Today\'s Panchang Overview\\n- **Tithi Clock**: Visual representation of the current lunar day\\n- **Nakshatra**: Current lunar mansion and its planetary lord\\n- **Vara**: The weekday and its ruling celestial body\\n- **Yoga**: The current yoga formed by Sun-Moon alignment\\n- **Karana**: Finer time divisions for precise timing\\n\\n### Astronomical Positions\\nReal-time tracking of:\\n- Sun\'s position in the sidereal zodiac\\n- Moon\'s position and speed\\n- Sun-Moon angle\\n- Ayanamsa (precession correction)\\n\\n### Tithi Guidance\\nBased on the current Tithi, the app provides:\\n- **Auspicious activities**: Recommended actions for the day\\n- **Activities to avoid**: Things that might be inauspicious\\n- **Spiritual insights**: Deeper meanings and reflections\\n\\nFor example, during Krishna Amavasya (new moon), the app suggests activities like ancestral offerings, deep meditation, and self-care, while advising against starting new ventures or long journeys.\\n\\n### Learning Resources\\nThe app includes a comprehensive learning guide explaining:\\n- The five elements of Panchang\\n- Sun and Moon cycles\\n- How to interpret and use this information in daily life\\n\\n### Personal Reflection Tracking\\nUsers can sign in with Google to:\\n- Log daily reflections\\n- Track personal patterns over time\\n- Discover correlations between Panchang elements and life events\\n\\n## Benefits of Using Panchanga Anveshana\\n\\n1. **Cultural Connection**: Reconnect with Vedic traditions and Indian heritage\\n2. **Mindful Living**: Make informed decisions based on traditional wisdom\\n3. **Spiritual Growth**: Use Panchang as a tool for introspection and self-awareness\\n4. **Daily Guidance**: Receive personalized recommendations for auspicious timing\\n5. **Educational Value**: Learn about astronomy, astrology, and ancient Indian knowledge systems\\n\\n## Who Can Benefit?\\n\\n- Individuals interested in Indian astrology and Vedic sciences\\n- Spiritual practitioners seeking daily guidance\\n- Those looking to incorporate traditional wisdom into modern life\\n- People curious about astronomical cycles and their influence\\n- Anyone wanting to explore mindfulness through time-based observations\\n\\n## Getting Started\\n\\nTo begin your journey with Panchanga Anveshana:\\n\\n1. Visit [https://pa.devity.in/](https://pa.devity.in/)\\n2. Allow location detection for accurate calculations\\n3. Explore today\'s Panchang\\n4. Sign in with Google to start tracking your reflections\\n5. Use the learning guide to deepen your understanding\\n\\nPanchanga Anveshana bridges the gap between ancient wisdom and modern technology, offering a unique way to observe, reflect, and discover patterns in life through the timeless cycles of Panchang time.","code":"var Component=(()=>{var g=Object.create;var r=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var m=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var f=(a,n)=>()=>(n||a((n={exports:{}}
1).exports,n),n.exports),v=(a,n)=>{for(var i in n)r(a,i,{get:n[i],enumerable:!0})},s=(a,n,i,t)=>{if(n&&typeof n==\\"object\\"||typeof n==\\"function\\")for(let l of u(n))!w.call(a,l)&&l!==i&&r(a,l,{get:()=>n[l],enumerable:!(t=p(n,l))||t.enumerable});return a};var x=(a,n,i)=>(i=a!=null?g(m(a)):{},s(n||!a||!a.__esModule?r(i,\\"default\\",{value:a,enumerable:!0}):i,a)),y=a=>s(r({},\\"__esModule\\",{value:!0}),a);var o=f((M,h)=>{h.exports=_jsx_runtime});var b={};v(b,{default:()=>d,frontmatter:()=>k});var e=x(o()),k={title:\\"Exploring Life Through Panchang Time: Panchanga Anveshana\\",date:\\"2026-04-17\\",lastmod:\\"2026-04-17\\",tags:[\\"Panchang\\",\\"Astrology\\",\\"Indian Calendar\\",\\"Spiritual Tools\\",\\"Vedic\\"],draft:!0,images:\\"/static/images/pa-screenshot.png\\",summary:\\"Discover Panchanga Anveshana, a modern tool for exploring life through Panchang time. Learn how this app helps users understand auspicious times, reflect on daily patterns, and align with Vedic traditions.\\",layout:\\"PostLayout\\",canonicalUrl:\\"https://blog.devity.in/panchanga-anveshana-exploring-life-through-panchang-time\\"};function c(a){let n={a:\\"a\\",h1:\\"h1\\",h2:\\"h2\\",h3:\\"h3\\",li:\\"li\\",ol:\\"ol\\",p:\\"p\\",path:\\"path\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",ul:\\"ul\\",...a.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsxs)(n.h1,{className:\\"content-header\\",id:\\"exploring-life-through-panchang-time-panchanga-anveshana\\",children:[(0,e.jsx)(n.a,{href:\\"#exploring-life-through-panchang-time-panchanga-anveshana\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Exploring Life Through Panchang Time: Panchanga Anveshana\\"]}),(0,e.jsx)(n.p,{children:\\"In the fast-paced world of modern living, many are turning back to ancient wisdom for guidance. Panchang, the traditional Indian astrological calendar, has been used for centuries to determine auspicious times for activities, festivals, and personal decisions. Now, with the advent of technology, tools like Panchanga Anveshana are making this ancient knowledge accessible and interactive.\\"}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"what-is-panchanga-anveshana\\",children:[(0,e.jsx)(n.a,{href:\\"#what-is-panchanga-anveshana\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What is Panchanga Anveshana?\\"]}),(0,e.jsxs)(n.p,{children:[\\"Panchanga Anveshana is a web-based application available at \\",(0,e.jsx)(n.a,{href:\\"https://pa.devity.in/\\",children:\\"pa.devity.in\\"}),\' that allows users to explore their lives through the lens of Panchang time. \\"Panchanga\\" means \\"five limbs\\" in Sanskrit, referring to the five key elements that describe every moment: Tithi (lunar day), Nakshatra (lunar mansion), Vara (weekday), Yoga (solar-lunar angle), and Karana (half tithi).\']}),(0,e.jsx)(n.p,{children:\\"The app provides today\'s Panchang at a glance, along with astronomical positions, guidance based on the current Tithi, and educational resources to help users understand these concepts.\\"}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"key-features\\",children:[(0,e.jsx)(n.a,{href:\\"#key-features\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Key Features\\"]}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"todays-panchang-overview\\",children:[(0,e.jsx)(n.a,{href:\\"#todays-panchang-overview\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Today\'s Panchang Overview\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Tithi Clock\\"}),\\": Visual representation of the current lunar day\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Nakshatra\\"}),\\": Current lunar mansion and its planetary lord\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Vara\\"}),\\": The weekday and its ruling celestial body\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Yoga\\"}),\\": The current yoga formed by Sun-Moon alignment\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Karana\\"}),\\": Finer time divisions for precise timing\\"]})]}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"astronomical-positions\\",children:[(0,e.jsx)(n.a,{href:\\"#astronomical-positions\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Astronomical Positions\\"]}),(0,e.jsx)(n.p,{children:\\"Real-time tracking of:\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsx)(n.li,{children:\\"Sun\'s position in the sidereal zodiac\\"}),(0,e.jsx)(n.li,{children:\\"Moon\'s position and speed\\"}),(0,e.jsx)(n.li,{children:\\"Sun-Moon angle\\"}),(0,e.jsx)(n.li,{children:\\"Ayanamsa (precession correction)\\"})]}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"tithi-guidance\\",children:[(0,e.jsx)(n.a,{href:\\"#tithi-guidance\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Tithi Guidance\\"]}),(0,e.jsx)(n.p,{children:\\"Based on the current Tithi, the app provides:\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Auspicious activities\\"}),\\": Recommended actions for the day\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Activities to avoid\\"}),\\": Things that might be inauspicious\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Spiritual insights\\"}),\\": Deeper meanings and reflections\\"]})]}),(0,e.jsx)(n.p,{children:\\"For example, during Krishna Amavasya (new moon), the app suggests activities like ancestral offerings, deep meditation, and self-care, while advising against starting new ventures or long journeys.\\"}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"learning-resources\\",children:[(0,e.jsx)(n.a,{href:\\"#learning-resources\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Learning Resources\\"]}),(0,e.jsx)(n.p,{children:\\"The app includes a comprehensive learning guide explaining:\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsx)(n.li,{children:\\"The five elements of Panchang\\"}),(0,e.jsx)(n.li,{children:\\"Sun and Moon cycles\\"}),(0,e.jsx)(n.li,{children:\\"How to interpret and use this information in daily life\\"})]}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"personal-reflection-tracking\\",children:[(0,e.jsx)(n.a,{href:\\"#personal-reflection-tracking\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Personal Reflection Tracking\\"]}),(0,e.jsx)(n.p,{children:\\"Users can sign in with Google to:\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsx)(n.li,{children:\\"Log daily reflections\\"}),(0,e.jsx)(n.li,{children:\\"Track personal patterns over time\\"}),(0,e.jsx)(n.li,{children:\\"Discover correlations between Panchang elements and life events\\"})]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"benefits-of-using-panchanga-anveshana\\",children:[(0,e.jsx)(n.a,{href:\\"#benefits-of-using-panchanga-anveshana\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Benefits of Using Panchanga Anveshana\\"]}),(0,e.jsxs)(n.ol,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Cultural Connection\\"}),\\": Reconnect with Vedic traditions and Indian heritage\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Mindful Living\\"}),\\": Make informed decisions based on traditional wisdom\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Spiritual Growth\\"}),\\": Use Panchang as a tool for introspection and self-awareness\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Daily Guidance\\"}),\\": Receive personalized recommendations for auspicious timing\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Educational Value\\"}),\\": Learn about astronomy, astrology, and ancient Indian knowledge systems\\"]})]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"who-can-benefit\\",children:[(0,e.jsx)(n.a,{href:\\"#who-can-benefit\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Who Can Benefit?\\"]}
1),(0,e.jsxs)(n.ul,{children:[(0,e.jsx)(n.li,{children:\\"Individuals interested in Indian astrology and Vedic sciences\\"}),(0,e.jsx)(n.li,{children:\\"Spiritual practitioners seeking daily guidance\\"}),(0,e.jsx)(n.li,{children:\\"Those looking to incorporate traditional wisdom into modern life\\"}),(0,e.jsx)(n.li,{children:\\"People curious about astronomical cycles and their influence\\"}),(0,e.jsx)(n.li,{children:\\"Anyone wanting to explore mindfulness through time-based observations\\"})]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"getting-started\\",children:[(0,e.jsx)(n.a,{href:\\"#getting-started\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Getting Started\\"]}),(0,e.jsx)(n.p,{children:\\"To begin your journey with Panchanga Anveshana:\\"}),(0,e.jsxs)(n.ol,{children:[(0,e.jsxs)(n.li,{children:[\\"Visit \\",(0,e.jsx)(n.a,{href:\\"https://pa.devity.in/\\",children:\\"https://pa.devity.in/\\"})]}),(0,e.jsx)(n.li,{children:\\"Allow location detection for accurate calculations\\"}),(0,e.jsx)(n.li,{children:\\"Explore today\'s Panchang\\"}),(0,e.jsx)(n.li,{children:\\"Sign in with Google to start tracking your reflections\\"}),(0,e.jsx)(n.li,{children:\\"Use the learning guide to deepen your understanding\\"})]}),(0,e.jsx)(n.p,{children:\\"Panchanga Anveshana bridges the gap between ancient wisdom and modern technology, offering a unique way to observe, reflect, and discover patterns in life through the timeless cycles of Panchang time.\\"})]})}function d(a={}){let{wrapper:n}=a.components||{};return n?(0,e.jsx)(n,{...a,children:(0,e.jsx)(c,{...a})}):c(a)}return y(b);})();\\n;return Component;"},"_id":"blog/panchanga-anveshana-exploring-life-through-panchang-time.mdx","_raw":{"sourceFilePath":"blog/panchanga-anveshana-exploring-life-through-panchang-time.mdx","sourceFileName":"panchanga-anveshana-exploring-life-through-panchang-time.mdx","sourceFileDir":"blog","contentType":"mdx","flattenedPath":"blog/panchanga-anveshana-exploring-life-through-panchang-time"},"type":"Blog","readingTime":{"text":"3 min read","minutes":2.645,"time":158700,"words":529},"slug":"panchanga-anveshana-exploring-life-through-panchang-time","path":"blog/panchanga-anveshana-exploring-life-through-panchang-time","filePath":"blog/panchanga-anveshana-exploring-life-through-panchang-time.mdx","toc":[{"value":"Exploring Life Through Panchang Time: Panchanga Anveshana","url":"#exploring-life-through-panchang-time-panchanga-anveshana","depth":1},{"value":"What is Panchanga Anveshana?","url":"#what-is-panchanga-anveshana","depth":2},{"value":"Key Features","url":"#key-features-2","depth":2},{"value":"Today\'s Panchang Overview","url":"#todays-panchang-overview","depth":3},{"value":"Astronomical Positions","url":"#astronomical-positions","depth":3},{"value":"Tithi Guidance","url":"#tithi-guidance","depth":3},{"value":"Learning Resources","url":"#learning-resources","depth":3},{"value":"Personal Reflection Tracking","url":"#personal-reflection-tracking","depth":3},{"value":"Benefits of Using Panchanga Anveshana","url":"#benefits-of-using-panchanga-anveshana","depth":2},{"value":"Who Can Benefit?","url":"#who-can-benefit","depth":2},{"value":"Getting Started","url":"#getting-started-1","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"Exploring Life Through Panchang Time: Panchanga Anveshana","datePublished":"2026-04-17T00:00:00.000Z","dateModified":"2026-04-17T00:00:00.000Z","description":"Discover Panchanga Anveshana, a modern tool for exploring life through Panchang time. Learn how this app helps users understand auspicious times, reflect on daily patterns, and align with Vedic traditions.","url":"https://www.devity.in/blog/panchanga-anveshana-exploring-life-through-panch
1ang-time/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/pa-screenshot.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"Rewriter â Flutter Desktop App for AI-Powered Clipboard Rewriting","date":"2025-02-03T00:00:00.000Z","tags":["Flutter","Desktop App","AI","Clipboard","Gemini","Ollama","devity-engineering"],"keywords":[],"lastmod":"2025-02-03T00:00:00.000Z","draft":false,"summary":"Download Rewriter â a free Flutter desktop app for macOS. Get the DMG, install, and use AI-powered clipboard rewriting with Gemini, Ollama, or local MediaPipe GenAI. No coding required.","images":"/static/images/rewriter-screenshot.png","layout":"PostLayout","canonicalUrl":"","faqs":[],"body":{"raw":"\\n# The Spark: The Friction of Rewriting Text\\n\\nEvery time you copy a sentence and want to rephrase it â for an email, a report, or a message â a familiar dance unfolds. You open a browser tab, paste into an AI tool, wait for the response, then copy the result back. Context switches. Tabs pile up. The flow breaks.\\n\\nMost AI writing tools live in the cloud or in separate apps. They donât sit where you already work: in the clipboard. You copy, then leave your flow to go somewhere else, paste, wait, and copy again. For quick rewrites â a tone change, a shorter version, a more formal phrasing â that round-trip is unnecessary friction.\\n\\nWhat if the clipboard itself could rewrite what you copy?\\n\\nThatâs where **Rewriter** comes in.\\n\\n## Download & Use\\n\\n**Want to use it right away?** Download the latest **DMG** from the [Rewriter Releases](https://github.com/devity-in/rewriter/releases) page, open it, drag Rewriter to Applications, and launch. No Flutter or command line needed â just install and use.\\n\\n- **macOS only** (Windows/Linux planned)\\n- **Free** â no subscription\\n- **First launch:** app appears in the menu bar â open **Settings**, pick an AI backend (Gemini, Ollama, or Local AI), configure once, then enable. After that, copy English text and the clipboard is rewritten automatically.\\n\\n## The Idea: Clipboard-First AI Rewriting\\n\\nRewriter is a Flutter desktop application that runs in the system tray, monitors clipboard changes, detects English sentences, rewrites them using AI, and automatically updates the clipboard with the rewritten content. No extra tabs, no manual pasteâcopy cycle â copy once, get a rewritten version in place.\\n\\nThe core vision:\\n\\n> Run silently in the background, detect when you copy English text, rewrite it with AI (Gemini, Ollama, or local MediaPipe GenAI), and put the result back on the clipboard â with optional preview, history, and dashboard.\\n\\n## What Problem Are We Solving?\\n\\n- **Context switching** â Leaving your flow to open a browser or another app just to rephrase text.\\n- **Manual pasteâcopy cycles** â Copy â open tool â paste â wait â copy result.\\n- **No clipboard-native option** â AI rewriting not integrated where you already copy and paste.\\n- **Privacy and offline needs** â Not everyone wants to send every snippet to the cloud.\\n- **One-size-fits-all tone** â Needing different styles (professional, casual, concise, academic) without changing tools.\\n\\n## How Rewriter Solves It\\n\\n### Core Functionality\\n\\n**System Tray Integration** â Runs in the background with a menu bar icon. No window to keep open; itâs there when you need it.\\n\\n**Automatic Clipboard Monitoring** â Detects when you copy English text and triggers a rewrite. No need to open an app or click a button.\\n\\n**AI-Powered Rewriting** â Uses Google Gemini API, Ollama, or local MediaPipe GenAI models to rewrite text in different styles.\\n\\n**Multiple AI Backends** â Choose what fits you:\\n- **Gemini** (cloud) â High quality, API key, internet required.\\n- **Ollama** (local server) â Run models like Gemma, Llama, Mistral locally; no API key.\\n- **Local AI (MediaPipe GenAI)** â Fully offline, no API key, privacy-focused.\\n\\n**Smart Language Detection** â Only processes English sentences, so other content stays untouched.\\n\\n**Automatic Clipboard Update** â Rewritten text replaces the clipboard content so you can paste immediately.\\n\\n### Configuration & Settings\\n\\n**Settings Window** â Dedicated UI for all options: AI backend, style, debounce, sentence length, and more.\\n\\n**Secure API Key Storage** â API keys stored with `flutter_secure_storage` (e.g. macOS Keychain).\\n\\n**Enable/Disable Toggle** â Turn rewriting on or off without quitting the app.\\n\\n**Writing Styles
1** â Professional, Casual, Concise, or Academic.\\n\\n**Advanced Settings** â Debounce delay, minimum and maximum sentence length.\\n\\n### User Experience\\n\\n**System Notifications** â macOS notifications when a rewrite is done.\\n\\n**Preview Window** â View full rewritten text (and comparison with original) before using it.\\n\\n**Status in Tray** â Visual feedback: processing, ready, or error.\\n\\n**Error Notifications** â Clear messages when something goes wrong.\\n\\n**Keyboard Shortcuts** â Quick access without touching the mouse:\\n- `Cmd+Shift+C` â Copy last rewritten text\\n- `Cmd+Shift+S` â Open settings\\n- `Cmd+Shift+T` â Toggle rewriting on/off\\n\\n**History** â Access the last 50 rewrites.\\n\\n**Dashboard** â Overview of todayâs and total rewrites, success vs error over time (1d/7d/30d), and recent history.\\n\\n## What You Need (For DMG Users)\\n\\n- **macOS** (Intel or Apple Silicon)\\n- **One AI backend** (pick one):\\n - **Gemini** â [Get a Google Gemini API key](https://makersuite.google.com/app/apikey), enter it in Settings\\n - **Ollama** â Install [Ollama](https://ollama.ai), run it (e.g. `ollama pull gemma2:2b`), set base URL and model in Settings\\n - **Local AI** â MediaPipe GenAI model file (see the projectâs LOCAL_AI_SETUP for setup)\\n\\nNo Flutter or dev environment required â the DMG is ready to run.\\n\\n## Build From Source (Optional)\\n\\nIf you prefer to build yourself (e.g. to contribute or run from source):\\n\\n- **Flutter SDK** ^3.10.1 \\n- Clone the repo, then:\\n\\n```bash\\ncd rewriter\\nflutter config --enable-native-assets\\nflutter pub get\\nflutter run -d macos\\n```\\n\\nRelease DMGs are built via GitHub Actions on version tags (e.g. `v1.0.0`); the same app is what you get when you download from Releases.\\n\\n## Usage in Practice\\n\\n**Automatic mode (default)** â Copy English text; Rewriter detects it, rewrites it, and updates the clipboard. A notification appears when done.\\n\\n**Preview** â When a rewrite completes, you can open the preview window to see original vs rewritten (and comparison view), then copy the version you want or rely on the shortcut.\\n\\n**Shortcuts** â Use `Cmd+Shift+C` to copy the last rewrite, `Cmd+Shift+S` for settings, and `Cmd+Shift+T` to toggle rewriting.\\n\\n## Architecture at a Glance\\n\\n- **Services** â Clipboard, Gemini, Ollama, local AI, notifications, etc. are separate services.\\n- **State** â Provider for app state.\\n- **Platform** â Native macOS tray, notifications, and hotkeys.\\n- **Storage** â API keys in secure storage; settings and history in SharedPreferences.\\n\\n## AI Model Options: Quick Comparison\\n\\n| Option | Pros | Cons |\\n| ------------ | ----------------------------- | ----------------------------- |\\n| **Gemini** | High quality, no local setup | API key, internet, usage limits |\\n| **Ollama** | Many models, local, no key | Install + run server + pull model |\\n| **Local AI** | Offline, no key, private | Model download, may be lower quality |\\n\\n## Limitations & Roadmap\\n\\n- Focused on macOS today; Windows and Linux are planned.\\n- One rewritten version per run (multiple versions may return in the future).\\n- Local AI: run one rewrite at a time (no concurrent requests).\\n- No built-in auto-update yet; onboarding can be improved.\\n\\nDownload the DMG, install, configure your preferred AI backend once, and you\'re set â Rewriter runs in the tray and rewrites what you copy, without leaving what you\'re doing.\\n\\n> **[Download Rewriter (DMG)](https://github.com/devity-in/rewriter/releases)** â macOS, free.\\n","code":"var Component=(()=>{var p=Object.create;var a=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var w=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var f=(r,n)=>()=>(n||r((n={exports:{}}).exports,n),n.exports),y=(r,n)=>{for(var i in n)a(r,i,{get:n[i],enumerable:!0})},o=(r,n,i,l)=>{if(n&&typeof n==\\"object\\"||typeof n==\\"function\\")for(let t of g(n))!m.call(r,t)&&t!==i&&a(r,t,{get:()=>n[t],enumerable:!(l=u(n,t))||l.enumerable});return r};var v=(r,n,i)=>(i=r!=null?p(w(r)):{}
1,o(n||!r||!r.__esModule?a(i,\\"default\\",{value:r,enumerable:!0}):i,r)),b=r=>o(a({},\\"__esModule\\",{value:!0}),r);var d=f((I,c)=>{c.exports=_jsx_runtime});var x={};y(x,{default:()=>h,frontmatter:()=>k});var e=v(d()),k={title:\\"Rewriter \\\\u2014 Flutter Desktop App for AI-Powered Clipboard Rewriting\\",date:\\"2025-02-03\\",lastmod:\\"2025-02-03\\",tags:[\\"Flutter\\",\\"Desktop App\\",\\"AI\\",\\"Clipboard\\",\\"Gemini\\",\\"Ollama\\",\\"devity-engineering\\"],draft:!1,images:\\"/static/images/rewriter-screenshot.png\\",summary:\\"Download Rewriter \\\\u2014 a free Flutter desktop app for macOS. Get the DMG, install, and use AI-powered clipboard rewriting with Gemini, Ollama, or local MediaPipe GenAI. No coding required.\\",layout:\\"PostLayout\\",canonicalUrl:\\"\\"};function s(r){let n={a:\\"a\\",blockquote:\\"blockquote\\",code:\\"code\\",h1:\\"h1\\",h2:\\"h2\\",h3:\\"h3\\",li:\\"li\\",p:\\"p\\",path:\\"path\\",pre:\\"pre\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",table:\\"table\\",tbody:\\"tbody\\",td:\\"td\\",th:\\"th\\",thead:\\"thead\\",tr:\\"tr\\",ul:\\"ul\\",...r.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsxs)(n.h1,{className:\\"content-header\\",id:\\"the-spark-the-friction-of-rewriting-text\\",children:[(0,e.jsx)(n.a,{href:\\"#the-spark-the-friction-of-rewriting-text\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Spark: The Friction of Rewriting Text\\"]}),(0,e.jsx)(n.p,{children:\\"Every time you copy a sentence and want to rephrase it \\\\u2014 for an email, a report, or a message \\\\u2014 a familiar dance unfolds. You open a browser tab, paste into an AI tool, wait for the response, then copy the result back. Context switches. Tabs pile up. The flow breaks.\\"}),(0,e.jsx)(n.p,{children:\\"Most AI writing tools live in the cloud or in separate apps. They don\\\\u2019t sit where you already work: in the clipboard. You copy, then leave your flow to go somewhere else, paste, wait, and copy again. For quick rewrites \\\\u2014 a tone change, a shorter version, a more formal phrasing \\\\u2014 that round-trip is unnecessary friction.\\"}),(0,e.jsx)(n.p,{children:\\"What if the clipboard itself could rewrite what you copy?\\"}),(0,e.jsxs)(n.p,{children:[\\"That\\\\u2019s where \\",(0,e.jsx)(n.strong,{children:\\"Rewriter\\"}),\\" comes in.\\"]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"download--use\\",children:[(0,e.jsx)(n.a,{href:\\"#download--use\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Download & Use\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Want to use it right away?\\"}),\\" Download the latest \\",(0,e.jsx)(n.strong,{children:\\"DMG\\"}),\\" from the \\",(0,e.jsx)(n.a,{href:\\"https://github.com/devity-in/rewriter/releases\\",children:\\"Rewriter Releases\\"}),\\" page, open it, drag Rewriter to Applications, and launch. No Flutter or command line needed \\\\u2014 just install and use.\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"macOS only\\"}),\\" (Windows/Linux planned)\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Free\\"}),\\" \\\\u2014 no subscription\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"First launch:\\"}),\\" app appears in the menu bar \\\\u2192 open \\",(0,e.jsx)(n.strong,{children:\\"Settings\\"}),\\", pick an AI backend (Gemini, Ollama, or Local AI), configure once, then enable. After that, copy English text and the clipboard is rewritten automatically.\\"]})]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"the-idea-clipboard-first-ai-rewriting\\",children:[(0,e.jsx)(n.a,{href:\\"#the-idea-clipboard-first-ai-rewriting\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Idea: Clipboard-First AI Rewriting\\"]}),(0,e.jsx)(n.p,{children:\\"Rewriter is a Flutter desktop application that runs in the system tray, monitors clipboard changes, detects English sentences, rewrites them using AI, and automatically updates the clipboard with the rewritten content. No extra tabs, no manual paste\\\\u2013copy cycle \\\\u2014 copy once, get a rewritten version in place.\\"}),(0,e.jsx)(n.p,{children:\\"The core vision:\\"}),(0,e.jsx)(n.blockquote,{children:(0,e.jsx)(n.p,{children:\\"Run silently in the background, detect when you copy English text, rewrite it with AI (Gemini, Ollama, or local MediaPipe GenAI), and put the result back on the clipboard \\\\u2014 with optional preview, history, and dashboard.\\"})}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"what-problem-are-we-solving\\",children:[(0,e.jsx)(n.a,{href:\\"#what-problem-are-we-solving\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Problem Are We Solving?\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Context switching\\"}),\\" \\\\u2014 Leaving your flow to open a browser or another app just to rephrase text.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Manual paste\\\\u2013copy cycles\\"}),\\" \\\\u2014 Copy \\\\u2192 open tool \\\\u2192 paste \\\\u2192 wait \\\\u2192 copy result.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"No clipboard-native option\\"}
1),\\" \\\\u2014 AI rewriting not integrated where you already copy and paste.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Privacy and offline needs\\"}),\\" \\\\u2014 Not everyone wants to send every snippet to the cloud.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"One-size-fits-all tone\\"}),\\" \\\\u2014 Needing different styles (professional, casual, concise, academic) without changing tools.\\"]})]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"how-rewriter-solves-it\\",children:[(0,e.jsx)(n.a,{href:\\"#how-rewriter-solves-it\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"How Rewriter Solves It\\"]}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"core-functionality\\",children:[(0,e.jsx)(n.a,{href:\\"#core-functionality\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Core Functionality\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"System Tray Integration\\"}),\\" \\\\u2014 Runs in the background with a menu bar icon. No window to keep open; it\\\\u2019s there when you need it.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Automatic Clipboard Monitoring\\"}),\\" \\\\u2014 Detects when you copy English text and triggers a rewrite. No need to open an app or click a button.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"AI-Powered Rewriting\\"}),\\" \\\\u2014 Uses Google Gemini API, Ollama, or local MediaPipe GenAI models to rewrite text in different styles.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Multiple AI Backends\\"}),\\" \\\\u2014 Choose what fits you:\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Gemini\\"}),\\" (cloud) \\\\u2014 High quality, API key, internet required.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Ollama\\"}),\\" (local server) \\\\u2014 Run models like Gemma, Llama, Mistral locally; no API key.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Local AI (MediaPipe GenAI)\\"}),\\" \\\\u2014 Fully offline, no API key, privacy-focused.\\"]})]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Smart Language Detection\\"}),\\" \\\\u2014 Only processes English sentences, so other content stays untouched.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Automatic Clipboard Update\\"}),\\" \\\\u2014 Rewritten text replaces the clipboard content so you can paste immediately.\\"]}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"configuration--settings\\",children:[(0,e.jsx)(n.a,{href:\\"#configuration--settings\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Configuration & Settings\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Settings Window\\"}),\\" \\\\u2014 Dedicated UI for all options: AI backend, style, debounce, sentence length, and more.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Secure API Key Storage\\"}),\\" \\\\u2014 API keys stored with \\",(0,e.jsx)(n.code,{children:\\"flutter_secure_storage\\"}),\\" (e.g. macOS Keychain).\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Enable/Disable Toggle\\"}),\\" \\\\u2014 Turn rewriting on or off without quitting the app.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Writing Styles\\"}),\\" \\\\u2014 Professional, Casual, Concise, or Academic.\\"]}
1),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Advanced Settings\\"}),\\" \\\\u2014 Debounce delay, minimum and maximum sentence length.\\"]}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"user-experience\\",children:[(0,e.jsx)(n.a,{href:\\"#user-experience\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"User Experience\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"System Notifications\\"}),\\" \\\\u2014 macOS notifications when a rewrite is done.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Preview Window\\"}),\\" \\\\u2014 View full rewritten text (and comparison with original) before using it.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Status in Tray\\"}),\\" \\\\u2014 Visual feedback: processing, ready, or error.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Error Notifications\\"}),\\" \\\\u2014 Clear messages when something goes wrong.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Keyboard Shortcuts\\"}),\\" \\\\u2014 Quick access without touching the mouse:\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.code,{children:\\"Cmd+Shift+C\\"}),\\" \\\\u2014 Copy last rewritten text\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.code,{children:\\"Cmd+Shift+S\\"}),\\" \\\\u2014 Open settings\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.code,{children:\\"Cmd+Shift+T\\"}),\\" \\\\u2014 Toggle rewriting on/off\\"]})]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"History\\"}),\\" \\\\u2014 Access the last 50 rewrites.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Dashboard\\"}),\\" \\\\u2014 Overview of today\\\\u2019s and total rewrites, success vs error over time (1d/7d/30d), and recent history.\\"]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"what-you-need-for-dmg-users\\",children:[(0,e.jsx)(n.a,{href:\\"#what-you-need-for-dmg-users\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What You Need (For DMG Users)\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"macOS\\"}),\\" (Intel or Apple Silicon)\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"One AI backend\\"}),\\" (pick one):\\",(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Gemini\\"}),\\" \\\\u2014 \\",(0,e.jsx)(n.a,{href:\\"https://makersuite.google.com/app/apikey\\",children:\\"Get a Google Gemini API key\\"}),\\", enter it in Settings\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Ollama\\"}),\\" \\\\u2014 Install \\",(0,e.jsx)(n.a,{href:\\"https://ollama.ai\\",children:\\"Ollama\\"}),\\", run it (e.g. \\",(0,e.jsx)(n.code,{children:\\"ollama pull gemma2:2b\\"}),\\"), set base URL and model in Settings\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Local AI\\"}),\\" \\\\u2014 MediaPipe GenAI model file (see the project\\\\u2019s LO
1CAL_AI_SETUP for setup)\\"]})]})]})]}),(0,e.jsx)(n.p,{children:\\"No Flutter or dev environment required \\\\u2014 the DMG is ready to run.\\"}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"build-from-source-optional\\",children:[(0,e.jsx)(n.a,{href:\\"#build-from-source-optional\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Build From Source (Optional)\\"]}),(0,e.jsx)(n.p,{children:\\"If you prefer to build yourself (e.g. to contribute or run from source):\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Flutter SDK\\"}),\\" ^3.10.1\\"]}),(0,e.jsx)(n.li,{children:\\"Clone the repo, then:\\"})]}),(0,e.jsx)(n.pre,{className:\\"language-bash\\",children:(0,e.jsxs)(n.code,{className:\\"language-bash code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token builtin class-name\\",children:\\"cd\\"}),` rewriter\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`flutter config --enable-native-assets\\n`}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`flutter pub get\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"flutter run \\",(0,e.jsx)(n.span,{className:\\"token parameter variable\\",children:\\"-d\\"}),` macos\\n`]})]})}),(0,e.jsxs)(n.p,{children:[\\"Release DMGs are built via GitHub Actions on version tags (e.g. \\",(0,e.jsx)(n.code,{children:\\"v1.0.0\\"}),\\"); the same app is what you get when you download from Releases.\\"]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"usage-in-practice\\",children:[(0,e.jsx)(n.a,{href:\\"#usage-in-practice\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Usage in Practice\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Automatic mode (default)\\"}),\\" \\\\u2014 Copy English text; Rewriter detects it, rewrites it, and updates the clipboard. A notification appears when done.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Preview\\"}),\\" \\\\u2014 When a rewrite completes, you can open the preview window to see original vs rewritten (and comparison view), then copy the version you want or rely on the shortcut.\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Shortcuts\\"}),\\" \\\\u2014 Use \\",(0,e.jsx)(n.code,{children:\\"Cmd+Shift+C\\"}),\\" to copy the last rewrite, \\",(0,e.jsx)(n.code,{children:\\"Cmd+Shift+S\\"}),\\" for settings, and \\",(0,e.jsx)(n.code,{children:\\"Cmd+Shift+T\\"}),\\" to toggle rewriting.\\"]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"architecture-at-a-glance\\",children:[(0,e.jsx)(n.a,{href:\\"#architecture-at-a-glance\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Architecture at a Glance\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Services\\"}),\\" \\\\u2014 Clipboard, Gemini, Ollama, local AI, notifications, etc. are separate services.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"State\\"}),\\" \\\\u2014 Provider for app state.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Platform\\"}),\\" \\\\u2014 Native macOS tray, notifications, and hotkeys.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Storage\\"}),\\" \\\\u2014 API keys in secure storage; settings and history in SharedPreferences.\\"]})]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"ai-model-options-quick-comparison\\",children:[(0,e.jsx)(n.a,{href:\\"#ai-model-options-quick-comparison\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"AI Model Options: Quick Comparison\\"]}),(0,e.jsxs)(n.table,{children:[(0,e.jsx)(n.thead,{children:(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.th,{children:\\"Option\\"}),(0,e.jsx)(n.th,{children:\\"Pros\\"}),(0,e.jsx)(n.th,{children:\\"Cons\\"})]})}),(0,e.jsxs)(n.tbody,{children:[(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:(0,e.jsx)(n.strong,{children:\\"Gemini\\"})}),(0,e.jsx)(n.td,{children:\\"High quality, no local setup\\"}),(0,e.jsx)(n.td,{children:\\"API key, internet, usage limits\\"})]}),(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:(0,e.jsx)(n.strong,{children:\\"Ollama\\"})}),(0,e.jsx)(n.td,{children:\\"Many models, local, no key\\"}),(0,e.jsx)(n.td,{children:\\"Install + run server + pull model\\"})]}),(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:(0,e.jsx)(n.strong,{children:\\"Local AI\\"})}),(0,e.jsx)(n.td,{children:\\"Offline, no key, private\\"}),(0,e.jsx)(n.td,{children:\\"Model download, may be lower quality\\"})]})]})]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"limitations--roadmap\\",children:[(0,e.jsx)(n.a,{href:\\"#limitations--roadmap\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Limitations & Roadmap\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsx)(n.li,{children:\\"Focused on macOS today; Windows and Linux are planned.\\"}),(0,e.jsx)(n.li,{children:\\"One rewritten version per run (multiple versions may return in the future).\\"}),(0,e.jsx)(n.li,{children:\\"Local AI: run one rewrite at a time (no concurrent requests).\\"}),(0,e.jsx)(n.li,{children:\\"No built-in auto-update yet; onboarding can be improved.\\"})]}),(0,e.jsx)(n.p,{children:\\"Download the DMG, install, configure your preferred AI backend once, and you\'re set \\\\u2014 Rewriter runs in the tray and rewrites what you copy, without leaving what you\'re doing.\\"}),(0,e.jsx)(n.blockquote,{children:(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:(0,e.jsx)(n.a,{href:\\"https://github.com/devity-in/rewriter/releases\\",children:\\"Download Rewriter (DMG)\\"})}),\\" \\\\u2014 macOS, free.\\"]})})]})}function h(r={}){let{wrapper:n}=r.components||{};return n?(0,e.jsx)(n,{...r,children:(0,e.jsx)(s,{...r})}):s(r)}return b(x);})();\\n;return Component;"},"_id":"blog/rewriter-flutter-desktop-clipboard-ai-rewriting.mdx","_raw":{"sourceFilePath":"blog/rewriter-flutter-desktop-clipboard-ai-rewriting.mdx","sourceFileName":"rewriter-flutter-desktop-clipboard-ai-rewriting.mdx","sourceFileDir":"blog","contentType":"mdx","flattenedPath":"blog/rewriter-flutter-desktop-clipboard-ai-rewriting"},"type":"Blog","readingTime":{"text":"6 min read","minutes":5.58,"time":334800,"words":1116},"slug":"rewriter-flutter-desktop-clipboard-ai-rewriting","path":"blog/rewriter-flutter-desktop-clipboard-ai-rewriting","filePath":"blog/rewriter-flutter-desktop-clipboard-ai-rewriting.mdx","toc":[{"value":"The Spark: The Friction of Rewriting Text","url":"#the-spark-the-friction-of-rewriting-text","depth":1},{"value":"Download & Use","url":"#download--use","depth":2},{"value":"The Idea: Clipboard-First AI Rewriting","url":"#the-idea-clipboard-first-ai-rewriting","depth":2},{"value":"What Problem Are We Solving?","url":"#what-problem-are-we-solving-5","depth":2},{"value":"How Rewriter Solves It","url":"#how-rewriter-solves-it","depth":2},{"value":"Core Functionality","url":"#core-functionality","depth":3},{"value":"Configuration & Settings","url":"#configuration--settings","depth":3},{"value":"User Experience","url":"#user-experience","depth":3},{"value":"What You Need (For DMG Users)","url":"#what-you-need-for-dmg-users","depth":2},{"value":"Build From Source (Optional)","url":"#build-from-source-optional","depth":2},{"value":"Usage in Practice","url":"#usage-in-practice","depth":2},{"value":"Architecture at a Glance","url":"#architecture-at-a-glance","depth":2},{"value":"AI Model Options: Quick Comparison","url":"#ai-model-options-quick-comparison","depth":2},{"value":"Limitations & Roadmap","url":"#limitations--roadmap","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"Rewriter â Flutter Desktop App for AI-Powered Clipboard Rewriting","datePublished":"2025-02-03T00:00:00.000Z","dateModified":"2025-02-03T00:00:00.000Z","description":"Download Rewriter â a free Flutter desktop app for macOS. Get the DMG, install, and use AI-powered clipboard rewriting with Gemini, Ollama, or local MediaPipe GenAI. No coding required.","url":"https://www.devity.in/blog/rewriter-flutter-desktop-clipboard-ai-rewriting/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/rewriter-screenshot.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"TailorFlow â A Privacy-First, Offline-Capable Digital Ledger for Tailors","date":"2026-04-21T00:00:00.000Z","tags":["Web App","Tailor","Offline-First","PWA","SQLite WASM","Privacy","devity-engineering"],"keywords":[],"lastmod":"2026-04-21T00:00:00.000Z","draft":false,"summary":"TailorFlow is a privacy-first, offline-capable digital ledger for tailors and clothing businesses. Replaces physical order registers with a searchable, measurement-focused system where you own 100% of your data.","images":"/static/images/tailorflow-screenshot.png","layout":"PostLayout","canonicalUrl":"","faqs":[],"body":{"raw":"\\n# The Spark: The Register Under the Counter\\n\\nEvery tailoring shop has one â a thick, worn-out register under the counter. Customer names, phone numbers, measurements, delivery dates, advance payments, fabric notes. Years of a business packed between its covers. Flip a few pages and you can see the history of a loyal customer. Lose it, and years of relationships go with it.\\n\\nMost tailors have tried âgoing digitalâ at some point â a notes app, an Excel sheet, a generic invoicing tool. None of them fit. Measurement fields donât exist. Fabric photos live in a separate gallery. Delivery dates drift into a different calendar. The register, flawed as it is, still holds everything in one place.\\n\\nThen thereâs the internet problem. Many shops sit in areas with patchy connectivity, and the last thing a tailor wants is a tool that stops working when the Wi-Fi does. And cloud-first tools raise another question that rarely gets asked out loud: *whose data is this, really?*\\n\\nThatâs where [**TailorFlow**](https://tailor.devity.in) comes in.\\n\\n## The Idea: A Digital Register That Stays Yours\\n\\
1nWhat if the physical register became digital â without becoming someone elseâs?\\n\\nWhat if a tailor could:\\n\\n- Store customers, measurements, orders, payments, and fabric photos in one place.\\n- Search across years of work in a second.\\n- Keep working when the internet is gone.\\n- Own 100% of the data â stored on their own device, synced to their own Google Drive.\\n- Install it on a phone like any other app.\\n- Print invoices, track advances and balances, and export reports when they need them.\\n\\nTailors would get the familiarity of a register, the speed of software, and the privacy of owning their own data. No subscription to a central server. No shop data sitting in someone elseâs database.\\n\\nThis is the core vision of **TailorFlow**:\\n\\n> A digital ledger built for how tailors actually work â offline-first, measurement-focused, and owned entirely by the shop.\\n\\n## What Problem Are We Solving?\\n\\n- Physical registers that get lost, damaged, or left behind.\\n- Generic invoicing apps that have no concept of measurements, garments, or fabrics.\\n- Cloud-first tools that stop working the moment the internet drops.\\n- Customer data sitting on a vendorâs servers, tied to a subscription.\\n- Fabric photos, measurements, and order details scattered across notes, galleries, and WhatsApp.\\n- No easy way to see top customers, monthly revenue, or garment-level trends.\\n\\n## How TailorFlow Solves It\\n\\nâ
**Customer Management**: \\nStore customer profiles with contact info and default measurements. Find any customer in seconds â by name, phone, or order.\\n\\nâ
**Order Tracking**: \\nCreate orders with invoice numbers, delivery dates, and a clear status lifecycle: *pending â in-progress â ready â delivered.* Supports both new stitching and alteration orders.\\n\\nâ
**Measurements Per Garment**: \\nDedicated measurement capture for Shirts, Pants, Kurtas, Lehengas, Blouses, and more. Each garment has its own fields â the way tailors actually measure.\\n\\nâ
**Fabric Photography**: \\nCamera integration to capture fabrics and designs right from the device. No more juggling the gallery app.\\n\\nâ
**Payments, Advances & Balances**: \\nRecord payments per order. Track advances received and balances due without a separate ledger.\\n\\nâ
**Pr
1intable Invoices**: \\nGenerate print-friendly invoices on demand. Hand over a proper receipt without extra tools.\\n\\nâ
**3D Mannequin**: \\nA Three.js-powered body model to visualize measurements â useful for training, clarity, and customer conversations.\\n\\nâ
**Reports & Analytics**: \\nRevenue by month, garment breakdown, top customers, CSV export. See your business, not just your orders.\\n\\nâ
**Shop Settings**: \\nConfigurable shop details, garment types, and pricing templates so the app matches how your shop actually runs.\\n\\n## Offline-First Architecture\\n\\nAll data lives in **SQLite WASM** running entirely in the browser, persisted via **OPFS**. Thereâs no central server database. Google Drive is used only as your personal backup and sync layer â the app auto-syncs your database and fabric photos to **your** Drive under `My Drive/tailor.devity.in/`.\\n\\n- Works fully offline after first load.\\n- Installable as a **PWA** â add to home screen and use it like a native app.\\n- **Service Worker** for background sync when connectivity returns.\\n- Data stays on your device; Drive stays under your account; no third-party database in the middle.\\n\\n## What Makes It Different\\n\\n**1. Built For Tailors, Not Retrofitted** \\nMeasurements, garments, fabrics, and alterations are first-class concepts â not hacks on top of a generic invoicing tool.\\n\\n**2. Offline-First, Not Offline-Afterthought** \\nThe database lives on the device. Connectivity is optional. The shop keeps running when the internet doesnât.\\n\\n**3. You Own Your Data** \\nSQLite on your device, backups in your Drive. No subscription-gated database, no vendor lock-in, nothing you canât walk away with.\\n\\n**4. Measurement-Focused** \\nPer-garment measurement fields and a 3D mannequin reflect how tailors think â not how spreadsheets think.\\n\\n**5. Installable, Fast, Simple** \\nPWA install, service worker, SQLite WASM â a modern stack that shows up as a snappy app on a phone, tablet, or shop counter laptop.\\n\\n## Tech Stack\\n\\n| Layer | Technology |\\n| --------- | --------------------------------------- |\\n| Framework | Next.js 16 (App Router, TypeScript) |\\n| UI | React 19, Tailwind CSS 4 |\\n| Database | SQLite WASM (client-side, OPFS) |\\n| Auth | NextAuth.js with Google OAuth 2.0 |\\n| 3D | Three.js, @react-three/fiber |\\n| Sync | Google Drive API v3 |\\n| Hosting | Firebase App Hosting |\\n\\n## Key Workflows\\n\\n### New Order\\n\\n1. Pick an existing customer or create a new one.\\n2. Select garment type (Shirt, Pant, Kurta, Lehenga, Blouse, â¦).\\n3. Capture measurements â either from the customerâs defaults or fresh for this order.\\n4. Snap fabric and design photos via the camera.\\n5. Record advance payment and set delivery date.\\n6. Order moves through *pending â in-progress â ready â delivered*.\\n\\n### Alterations\\n\\nAlteration-type orders sit alongside new stitching orders in the same ledger, with their own flow â so a shop that does both doesnât need two systems.\\n\\n### Reports\\n\\nSee revenue by month, garment-wise breakdown, and top customers at a glance. Export to CSV when you need to share with an accountant or keep an external backup.\\n\\n## Your Data, Your Control\\n\\n- **Local-first** â the database lives in your browserâs OPFS, on your device.\\n- **Your Drive, your backup** â sync targets `My Drive/tailor.devity.in/` on your own Google account.\\n- **Scope-limited access** â uses Googleâs `drive.file` scope, so the app can only see files it created.\\n- **No central shop database** â thereâs no server holding every shopâs customer list.\\n- **Portable** â your data is a SQLite file you can open anywhere.\\n\\n## Perfect For\\n\\n- Independent tailors and boutique stitching shops.\\n- Small tailoring businesses with multiple staff but no dedicated IT.\\n- Shops in areas with patchy internet.\\n- Owners who want to modernize the register without handing their data to a SaaS vendor.\\n- Businesses doing both new stitching and alterations.\\n\\n## Great For\\n\\n- Replacing physical order registers.\\n- Tracking measurements and fabric photos per order.\\n- Managing advances, balances, and delivery dates.\\n- Printing invoices and handing over professional receipts.\\n- Understanding monthly revenue and top customers.\\n- Keeping years of customer history searchable.\\n\\n## The Future: The Register, Reimagined\\n\\nWith **TailorFlow**, the register under the counter becomes a fast, searchable, measurement-aware app â on your phone, on your counter laptop, on your tablet â without giving up ownership of your data or your ability to work offline.\\n\\nThis is more than a digital register.\\n\\n> Itâs a quiet upgrade to how tailoring shops run â privacy-first, offline-capable, and entirely yours.\\n\\n> **[Open TailorFlow](https://tailor.devity.in)** â works on any modern browser, installable as an app.\\n","code":"var Component=(()=>{var p=Object.create;var i=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var w=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var f=(a,r)=>()=>(r||a((r={exports:{}}).exports,r),r.exports),y=(a,r)=>{for(var n in r)i(a,n,{get:r[n],enumerable:!0})},o=(a,r,n,l)=>{if(r&&typeof r==\\"object\\"||typeof r==\\"function\\")for(let t of g(r))!m.call(a,t)&&t!==n&&i(a,t,{get:()=>r[t],enumerable:!(l=u(r,t))||l.enumerable});return a};var v=(a,r,n)=>(n=a!=null?p(w(a)):{},o(r||!a||!a.__esModule?i(n,\\"default\\",{value:a,enumerable:!0}):n,a)),b=a=>o(i({}
1,\\"__esModule\\",{value:!0}),a);var d=f((M,s)=>{s.exports=_jsx_runtime});var x={};y(x,{default:()=>c,frontmatter:()=>k});var e=v(d()),k={title:\\"TailorFlow \\\\u2014 A Privacy-First, Offline-Capable Digital Ledger for Tailors\\",date:\\"2026-04-21\\",lastmod:\\"2026-04-21\\",tags:[\\"Web App\\",\\"Tailor\\",\\"Offline-First\\",\\"PWA\\",\\"SQLite WASM\\",\\"Privacy\\",\\"devity-engineering\\"],draft:!1,images:\\"/static/images/tailorflow-screenshot.png\\",summary:\\"TailorFlow is a privacy-first, offline-capable digital ledger for tailors and clothing businesses. Replaces physical order registers with a searchable, measurement-focused system where you own 100% of your data.\\",layout:\\"PostLayout\\",canonicalUrl:\\"\\"};function h(a){let r={a:\\"a\\",blockquote:\\"blockquote\\",br:\\"br\\",code:\\"code\\",em:\\"em\\",h1:\\"h1\\",h2:\\"h2\\",h3:\\"h3\\",li:\\"li\\",ol:\\"ol\\",p:\\"p\\",path:\\"path\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",table:\\"table\\",tbody:\\"tbody\\",td:\\"td\\",th:\\"th\\",thead:\\"thead\\",tr:\\"tr\\",ul:\\"ul\\",...a.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsxs)(r.h1,{className:\\"content-header\\",id:\\"the-spark-the-register-under-the-counter\\",children:[(0,e.jsx)(r.a,{href:\\"#the-spark-the-register-under-the-counter\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Spark: The Register Under the Counter\\"]}),(0,e.jsx)(r.p,{children:\\"Every tailoring shop has one \\\\u2014 a thick, worn-out register under the counter. Customer names, phone numbers, measurements, delivery dates, advance payments, fabric notes. Years of a business packed between its covers. Flip a few pages and you can see the history of a loyal customer. Lose it, and years of relationships go with it.\\"}),(0,e.jsx)(r.p,{children:\\"Most tailors have tried \\\\u201Cgoing digital\\\\u201D at some point \\\\u2014 a notes app, an Excel sheet, a generic invoicing tool. None of them fit. Measurement fields don\\\\u2019t exist. Fabric photos live in a separate gallery. Delivery dates drift into a different calendar. The register, flawed as it is, still holds everything in one place.\\"}),(0,e.jsxs)(r.p,{children:[\\"Then there\\\\u2019s the internet problem. Many shops sit in areas with patchy connectivity, and the last thing a tailor wants is a tool that stops working when the Wi-Fi does. And cloud-first tools raise another question that rarely gets asked out loud: \\",(0,e.jsx)(r.em,{children:\\"whose data is this, really?\\"})]}),(0,e.jsxs)(r.p,{children:[\\"That\\\\u2019s where \\",(0,e.jsx)(r.a,{href:\\"https://tailor.devity.in\\",children:(0,e.jsx)(r.strong,{children:\\"TailorFlow\\"})}),\\" comes in.\\"]}),(0,e.jsxs)(r.h2,{className:\\"content-header\\",id:\\"the-idea-a-digital-register-that-stays-yours\\",children:[(0,e.jsx)(r.a,{href:\\"#the-idea-a-digital-register-that-stays-yours\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Idea: A Digital Register That Stays Yours\\"]}),(0,e.jsx)(r.p,{children:\\"What if the physical register became digital \\\\u2014 without becoming someone else\\\\u2019s?\\"}
1),(0,e.jsx)(r.p,{children:\\"What if a tailor could:\\"}),(0,e.jsxs)(r.ul,{children:[(0,e.jsx)(r.li,{children:\\"Store customers, measurements, orders, payments, and fabric photos in one place.\\"}),(0,e.jsx)(r.li,{children:\\"Search across years of work in a second.\\"}),(0,e.jsx)(r.li,{children:\\"Keep working when the internet is gone.\\"}),(0,e.jsx)(r.li,{children:\\"Own 100% of the data \\\\u2014 stored on their own device, synced to their own Google Drive.\\"}),(0,e.jsx)(r.li,{children:\\"Install it on a phone like any other app.\\"}),(0,e.jsx)(r.li,{children:\\"Print invoices, track advances and balances, and export reports when they need them.\\"})]}),(0,e.jsx)(r.p,{children:\\"Tailors would get the familiarity of a register, the speed of software, and the privacy of owning their own data. No subscription to a central server. No shop data sitting in someone else\\\\u2019s database.\\"}),(0,e.jsxs)(r.p,{children:[\\"This is the core vision of \\",(0,e.jsx)(r.strong,{children:\\"TailorFlow\\"}),\\":\\"]}),(0,e.jsx)(r.blockquote,{children:(0,e.jsx)(r.p,{children:\\"A digital ledger built for how tailors actually work \\\\u2014 offline-first, measurement-focused, and owned entirely by the shop.\\"})}),(0,e.jsxs)(r.h2,{className:\\"content-header\\",id:\\"what-problem-are-we-solving\\",children:[(0,e.jsx)(r.a,{href:\\"#what-problem-are-we-solving\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Problem Are We Solving?\\"]}),(0,e.jsxs)(r.ul,{children:[(0,e.jsx)(r.li,{children:\\"Physical registers that get lost, damaged, or left behind.\\"}),(0,e.jsx)(r.li,{children:\\"Generic invoicing apps that have no concept of measurements, garments, or fabrics.\\"}),(0,e.jsx)(r.li,{children:\\"Cloud-first tools that stop working the moment the internet drops.\\"}),(0,e.jsx)(r.li,{children:\\"Customer data sitting on a vendor\\\\u2019s servers, tied to a subscription.\\"}),(0,e.jsx)(r.li,{children:\\"Fabric photos, measurements, and order details scattered across notes, galleries, and WhatsApp.\\"}),(0,e.jsx)(r.li,{children:\\"No easy way to see top customers, monthly revenue, or garment-level trends.\\"})]}),(0,e.jsxs)(r.h2,{className:\\"content-header\\",id:\\"how-tailorflow-solves-it\\",children:[(0,e.jsx)(r.a,{href:\\"#how-tailorflow-solves-it\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"How TailorFlow Solves It\\"]}),(0,e.jsxs)(r.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(r.strong,{children:\\"Customer Management\\"}),\\":\\",(0,e.jsx)(r.br,{}),\\"Store customer profiles with contact info and default measurements. Find any customer in seconds \\\\u2014 by name, phone, or order.\\"]}),(0,e.jsxs)(r.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(r.strong,{children:\\"Order Tracking\\"}),\\":\\",(0,e.jsx)(r.br,{}),\\"Create orders with invoice numbers, delivery dates, and a clear status lifecycle: \\",(0,e.jsx)(r.em,{children:\\"pen
1ding \\\\u2192 in-progress \\\\u2192 ready \\\\u2192 delivered.\\"}),\\" Supports both new stitching and alteration orders.\\"]}),(0,e.jsxs)(r.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(r.strong,{children:\\"Measurements Per Garment\\"}),\\":\\",(0,e.jsx)(r.br,{}),\\"Dedicated measurement capture for Shirts, Pants, Kurtas, Lehengas, Blouses, and more. Each garment has its own fields \\\\u2014 the way tailors actually measure.\\"]}),(0,e.jsxs)(r.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(r.strong,{children:\\"Fabric Photography\\"}),\\":\\",(0,e.jsx)(r.br,{}),\\"Camera integration to capture fabrics and designs right from the device. No more juggling the gallery app.\\"]}),(0,e.jsxs)(r.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(r.strong,{children:\\"Payments, Advances & Balances\\"}),\\":\\",(0,e.jsx)(r.br,{}),\\"Record payments per order. Track advances received and balances due without a separate ledger.\\"]}),(0,e.jsxs)(r.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(r.strong,{children:\\"Printable Invoices\\"}),\\":\\",(0,e.jsx)(r.br,{}),\\"Generate print-friendly invoices on demand. Hand over a proper receipt without extra tools.\\"]}),(0,e.jsxs)(r.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(r.strong,{children:\\"3D Mannequin\\"}),\\":\\",(0,e.jsx)(r.br,{}),\\"A Three.js-powered body model to visualize measurements \\\\u2014 useful for training, clarity, and customer conversations.\\"]}),(0,e.jsxs)(r.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(r.strong,{children:\\"Reports & Analytics\\"}),\\":\\",(0,e.jsx)(r.br,{}),\\"Revenue by month, garment breakdown, top customers, CSV export. See your business, not just your orders.\\"]}),(0,e.jsxs)(r.p,{children:[\\"\\\\u2705 \\",(0,e.jsx)(r.strong,{children:\\"Shop Settings\\"}),\\":\\",(0,e.jsx)(r.br,{}),\\"Configurable shop details, garment types, and pricing templates so the app matches how your shop actually runs.\\"]}),(0,e.jsxs)(r.h2,{className:\\"content-header\\",id:\\"offline-first-architecture\\",children:[(0,e.jsx)(r.a,{href:\\"#offline-first-architecture\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Offline-First Architecture\\"]}),(0,e.jsxs)(r.p,{children:[\\"All data lives in \\",(0,e.jsx)(r.strong,{children:\\"SQLite WASM\\"}),\\" running entirely in the browser, persisted via \\",(0,e.jsx)(r.strong,{children:\\"OPFS\\"}),\\". There\\\\u2019s no central server database. Google Drive is used only as your personal backup and sync layer \\\\u2014 the app auto-syncs your database and fabric photos to \\",(0,e.jsx)(r.strong,{children:\\"your\\"}),\\" Drive under \\",(0,e.jsx)(r.code,{children:\\"My Drive/tailor.devity.in/\\"}),\\".\\"]}),(0,e.jsxs)(r.ul,{children:[(0,e.jsx)(r.li,{children:\\"Works fully offline after first load.\\"}),(0,e.jsxs)(r.li,{children:[\\"Installable as a \\",(0,e.jsx)(r.strong,{children:\\"PWA\\"}),\\" \\\\u2014 add to home screen and use it like a native app.\\"]}),(0,e.jsxs)(r.li,{children:[(0,e.jsx)(r.strong,{children:\\"Service Worker\\"}),\\" for background sync when connectivity returns.\\"]}),(0,e.jsx)(r.li,{children:\\"Data stays on your device; Drive stays under your account; no third-party database in the middle.\\"})]}),(0,e.jsxs)(r.h2,{className:\\"content-header\\",id:\\"what-makes-it-different\\",children:[(0,e.jsx)(r.a,{href:\\"#what-makes-it-different\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Makes It Different\\"]}),(0,e.jsxs)(r.p,{children:[(0,e.jsx)(r.strong,{children:\\"1. Built For Tailors, Not Retrofitted\\"}),(0,e.jsx)(r.br,{}),\\"Measurements, garments, fabrics, and alterations are first-class concepts \\\\u2014 not hacks on top of a generic invoicing tool.\\"]}),(0,e.jsxs)(r.p,{children:[(0,e.jsx)(r.strong,{children:\\"2. Offline-First, Not Offline-Afterthought\\"}),(0,e.jsx)(r.br,{}),\\"The database lives on the device. Connectivity is optional. The shop keeps running when the internet doesn\\\\u2019t.\\"]}),(0,e.jsxs)(r.p,{children:[(0,e.jsx)(r.strong,{children:\\"3. You Own Your Data\\"}),(0,e.jsx)(r.br,{}),\\"SQLite on your device, backups in your Drive. No subscription-gated database, no vend
1or lock-in, nothing you can\\\\u2019t walk away with.\\"]}),(0,e.jsxs)(r.p,{children:[(0,e.jsx)(r.strong,{children:\\"4. Measurement-Focused\\"}),(0,e.jsx)(r.br,{}),\\"Per-garment measurement fields and a 3D mannequin reflect how tailors think \\\\u2014 not how spreadsheets think.\\"]}),(0,e.jsxs)(r.p,{children:[(0,e.jsx)(r.strong,{children:\\"5. Installable, Fast, Simple\\"}),(0,e.jsx)(r.br,{}),\\"PWA install, service worker, SQLite WASM \\\\u2014 a modern stack that shows up as a snappy app on a phone, tablet, or shop counter laptop.\\"]}),(0,e.jsxs)(r.h2,{className:\\"content-header\\",id:\\"tech-stack\\",children:[(0,e.jsx)(r.a,{href:\\"#tech-stack\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Tech Stack\\"]}),(0,e.jsxs)(r.table,{children:[(0,e.jsx)(r.thead,{children:(0,e.jsxs)(r.tr,{children:[(0,e.jsx)(r.th,{children:\\"Layer\\"}),(0,e.jsx)(r.th,{children:\\"Technology\\"})]})}),(0,e.jsxs)(r.tbody,{children:[(0,e.jsxs)(r.tr,{children:[(0,e.jsx)(r.td,{children:\\"Framework\\"}),(0,e.jsx)(r.td,{children:\\"Next.js 16 (App Router, TypeScript)\\"})]}),(0,e.jsxs)(r.tr,{children:[(0,e.jsx)(r.td,{children:\\"UI\\"}),(0,e.jsx)(r.td,{children:\\"React 19, Tailwind CSS 4\\"})]}),(0,e.jsxs)(r.tr,{children:[(0,e.jsx)(r.td,{children:\\"Database\\"}),(0,e.jsx)(r.td,{children:\\"SQLite WASM (client-side, OPFS)\\"})]}),(0,e.jsxs)(r.tr,{children:[(0,e.jsx)(r.td,{children:\\"Auth\\"}),(0,e.jsx)(r.td,{children:\\"NextAuth.js with Google OAuth 2.0\\"})]}),(0,e.jsxs)(r.tr,{children:[(0,e.jsx)(r.td,{children:\\"3D\\"}),(0,e.jsx)(r.td,{children:\\"Three.js, @react-three/fiber\\"})]}),(0,e.jsxs)(r.tr,{children:[(0,e.jsx)(r.td,{children:\\"Sync\\"}),(0,e.jsx)(r.td,{children:\\"Google Drive API v3\\"})]}),(0,e.jsxs)(r.tr,{children:[(0,e.jsx)(r.td,{children:\\"Hosting\\"}),(0,e.jsx)(r.td,{children:\\"Firebase App Hosting\\"})]})]})]}),(0,e.jsxs)(r.h2,{className:\\"content-header\\",id:\\"key-workflows\\",children:[(0,e.jsx)(r.a,{href:\\"#key-workflows\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Key Workflows\\"]}),(0,e.jsxs)(r.h3,{className:\\"content-header\\",id:\\"new-order\\",children:[(0,e.jsx)(r.a,{href:\\"#new-order\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"New Order\\"]}),(0,e.jsxs)(r.ol,{children:[(0,e.jsx)(r.li,{children:\\"Pick an existing customer or create a new one.\\"}),(0,e.jsx)(r.li,{children:\\"Select garment type (Shirt, Pant, Kurta, Lehenga, Blouse, \\\\u2026).\\"}),(0,e.jsx)(r.li,{children:\\"Capture measurements \\\\u2014 either from the customer\\\\u2019s defaults or fresh for this order.\\"}),(0,e.jsx)(r.li,{children:\\"Snap fabric and design photos via the camera.\\"}),(0,e.jsx)(r.li,{children:\\"Record advance payment and set delivery date.\\"}),(0,e.jsxs)(r.li,{children:[\\"Order moves through \\",(0,e.jsx)(r.em,{children:\\"pen
1ding \\\\u2192 in-progress \\\\u2192 ready \\\\u2192 delivered\\"}),\\".\\"]})]}),(0,e.jsxs)(r.h3,{className:\\"content-header\\",id:\\"alterations\\",children:[(0,e.jsx)(r.a,{href:\\"#alterations\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Alterations\\"]}),(0,e.jsx)(r.p,{children:\\"Alteration-type orders sit alongside new stitching orders in the same ledger, with their own flow \\\\u2014 so a shop that does both doesn\\\\u2019t need two systems.\\"}),(0,e.jsxs)(r.h3,{className:\\"content-header\\",id:\\"reports\\",children:[(0,e.jsx)(r.a,{href:\\"#reports\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Reports\\"]}),(0,e.jsx)(r.p,{children:\\"See revenue by month, garment-wise breakdown, and top customers at a glance. Export to CSV when you need to share with an accountant or keep an external backup.\\"}),(0,e.jsxs)(r.h2,{className:\\"content-header\\",id:\\"your-data-your-control\\",children:[(0,e.jsx)(r.a,{href:\\"#your-data-your-control\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Your Data, Your Control\\"]}),(0,e.jsxs)(r.ul,{children:[(0,e.jsxs)(r.li,{children:[(0,e.jsx)(r.strong,{children:\\"Local-first\\"}),\\" \\\\u2014 the database lives in your browser\\\\u2019s OPFS, on your device.\\"]}),(0,e.jsxs)(r.li,{children:[(0,e.jsx)(r.strong,{children:\\"Your Drive, your backup\\"}),\\" \\\\u2014 sync targets \\",(0,e.jsx)(r.code,{children:\\"My Drive/tailor.devity.in/\\"}),\\" on your own Google account.\\"]}),(0,e.jsxs)(r.li,{children:[(0,e.jsx)(r.strong,{children:\\"Scope-limited access\\"}),\\" \\\\u2014 uses Google\\\\u2019s \\",(0,e.jsx)(r.code,{children:\\"drive.file\\"}),\\" scope, so the app can only see files it created.\\"]}),(0,e.jsxs)(r.li,{children:[(0,e.jsx)(r.strong,{children:\\"No central shop database\\"}),\\" \\\\u2014 there\\\\u2019s no server holding every shop\\\\u2019s customer list.\\"]}),(0,e.jsxs)(r.li,{children:[(0,e.jsx)(r.strong,{children:\\"Portable\\"}),\\" \\\\u2014 your data is a SQLite file you can open anywhere.\\"]})]}),(0,e.jsxs)(r.h2,{className:\\"content-header\\",id:\\"perfect-for\\",children:[(0,e.jsx)(r.a,{href:\\"#perfect-for\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Perfect For\\"]}),(0,e.jsxs)(r.ul,{children:[(0,e.jsx)(r.li,{children:\\"Independent tailors and boutique stitching shops.\\"}),(0,e.jsx)(r.li,{children:\\"Small tailoring businesses with multiple staff but no dedicated IT.\\"}),(0,e.jsx)(r.li,{children:\\"Shops in areas with patchy internet.\\"}),(0,e.jsx)(r.li,{children:\\"Owners who want to modernize the register without handing their data to a SaaS vendor.\\"}),(0,e.jsx)(r.li,{children:\\"Businesses doing both new stitching and alterations.\\"})]}),(0,e.jsxs)(r.h2,{className:\\"content-header\\",id:\\"great-for\\",children:[(0,e.jsx)(r.a,{href:\\"#great-for\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Great For\\"]}),(0,e.jsxs)(r.ul,{children:[(0,e.jsx)(r.li,{children:\\"Replacing physical order registers.\\"}),(0,e.jsx)(r.li,{children:\\"Tracking measurements and fabric photos per order.\\"}),(0,e.jsx)(r.li,{children:\\"Managing advances, balances, and delivery dates.\\"}),(0,e.jsx)(r.li,{children:\\"Printing invoices and handing over professional receipts.\\"}),(0,e.jsx)(r.li,{children:\\"Understanding monthly revenue and top customers.\\"}),(0,e.jsx)(r.li,{children:\\"Keeping years of customer history searchable.\\"})]}),(0,e.jsxs)(r.h2,{className:\\"content-header\\",id:\\"the-future-the-register-reimagined\\",children:[(0,e.jsx)(r.a,{href:\\"#the-future-the-register-reimagined\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(r.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(r.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(r.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(r.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Future: The Register, Reimagined\\"]}),(0,e.jsxs)(r.p,{children:[\\"With \\",(0,e.jsx)(r.strong,{children:\\"TailorFlow\\"}),\\", the register under the counter becomes a fast, searchable, measurement-aware app \\\\u2014 on your phone, on your counter laptop, on your tablet \\\\u2014 without giving up ownership of your data or your ability to work offline.\\"]}),(0,e.jsx)(r.p,{children:\\"This is more than a digital register.\\"}),(0,e.jsx)(r.blockquote,{children:(0,e.jsx)(r.p,{children:\\"It\\\\u2019s a quiet upgrade to how tailoring shops run \\\\u2014 privacy-first, offline-capable, and entirely yours.\\"})}),(0,e.jsx)(r.blockquote,{children:(0,e.jsxs)(r.p,{children:[(0,e.jsx)(r.strong,{children:(0,e.jsx)(r.a,{href:\\"https://tailor.devity.in\\",children:\\"Open TailorFlow\\"})}),\\" \\\\u2014 works on any modern browser, installable as an app.\\"]})})]})}function c(a={}){let{wrapper:r}=a.components||{};return r?(0,e.jsx)(r,{...a,children:(0,e.jsx)(h,{...a})}):h(a)}return b(x);})();\\n;return Component;"},"_id":"blog/tailor-flow.mdx","_raw":{"sourceFilePath":"blog/tailor-flow.mdx","sourceFileName":"tailor-flow.mdx","sourceFileDir":"blog","contentType":"mdx","flattenedPath":"blog/tailor-flow"},"type":"Blog","readingTime":{"text":"7 min read","minutes":6.355,"time":381300,"words":1271},"slug":"tailor-flow","path":"blog/tailor-flow","filePath":"blog/tailor-flow.mdx","toc":[{"value":"The Spark: The Register Under the Counter","url":"#the-spark-the-register-under-the-counter","depth":1},{"value":"The Idea: A Digital Register That Stays Yours","url":"#the-idea-a-digital-register-that-stays-yours","depth":2},{"value":"What Problem Are We Solving?","url":"#what-problem-are-we-solving-6","depth":2},{"value":"How TailorFlow Solves It","url":"#how-tailorflow-solves-it","depth":2},{"value":"Offline-First Architecture","url":"#offline-first-architecture","depth":2},{"value":"What Makes It Different","url":"#what-makes-it-different-2","depth":2},{"value":"Tech Stack","url":"#tech-stack","depth":2},{"value":"Key Workflows","url":"#key-workflows","depth":2},{"value":"New Order","url":"#new-order","depth":3},{"value":"Alterations","url":"#alterations","depth":3},{"value":"Reports","url":"#reports","depth":3},{"value":"Your Data, Your Control","url":"#your-data-your-control","depth":2},{"value":"Perfect For","url":"#perfect-for-2","depth":2},{"value":"Great For","url":"#great-for-1","depth":2},{"value":"The Future: The Register, Reimagined","url":"#the-future-the-register-reimagined","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"TailorFlow â A Privacy-First, Offline-Capable Digital Ledger for Tailors","datePublished":"2026-04-21T00:00:00.000Z","dateModified":"2026-04-21T00:00:00.000Z","description":"TailorFlow is a privacy-first, offline-capable digital ledger for tailors and clothing businesses. Replaces physical order registers with a searchable, measurement-focused system where you own 100% of your data.","url":"https://www.devity.in/blog/tailor-flow/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/tailorflow-screenshot.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"Idempotency and Related Concepts","date":"2025-06-04T00:00:00.000Z","tags":["Technology"],"keywords":[],"lastmod":"2025-06-04T00:00:00.000Z","draft":false,"summary":"Idempotency refers to a property of certain operations, especially in computing and mathematics, where performing the operation multiple times produces the same result as performing it just once. In other words, an idempotent operation can be executed multiple times without changing the outcome after the first application.","images":"/static/images/blog/idempotency-and-related-concepts.png","layout":"PostLayout","canonicalUrl":"https://blog.devity.in/technology/idempotency-and-related-concepts/","faqs":[],"body":{"raw":"\\n\\n\\n# Idempotent HTTP Methods in RESTful APIs\\n\\nIn RESTful APIs, **idempotency** ensures that making the same request multiple times has the same effect as making it once. In other words, repeated calls do not further change the serverâs state.\\n\\nThe MDN Web Docs define an idempotent HTTP method as one whose effect on the server of a single request is the same as for several identical requests. For example:\\n\\n- **GET** (read) is idempotent because fetching a resource repeatedly does not alter it.\\n- **DELETE** is idempotent because deleting a resource twice leaves it in the same âdeletedâ state (the first call succeeds; subsequent calls find nothing to delete).\\n\\nBy contrast, **POST** usually creates new resources on each call, so it is **not idempotent**.\\n\\nAs noted by HackerNoon, the methods `GET`, `PUT`, `DELETE`, `HEAD`, `OPTIONS`, and `TRACE` are idempotent, whereas `POST` and `PATCH` are not. In practice, this means clients can safely retry idempotent calls if they time out, without worrying about unintended side effects.\\n\\n## Summary of HTTP Methods\\n\\n- **GET / HEAD / OPTIONS / TRACE**: Read-only requests that do not modify state. Repeating them returns (nearly) the same response and leaves the server unchanged.\\n- **PUT**: Replaces or updates a resource. Issuing the same PUT repeatedly ends with the same final state (resource content).\\n- **DELETE**: Removes a resource. After the first successful delete, subsequent DELETEs do n
1othing new (the resource is already gone).\\n- **POST / PATCH**: Generally not idempotent. Each POST typically creates a new entity or has a distinct effect, so re-sending it will duplicate work.\\n\\nAll **safe HTTP methods** (those that only read data) are by definition idempotent. PUT and DELETE are also idempotent, while POST is not.\\n\\nUnderstanding these differences helps design more reliable APIs and informs how clients should retry requests.\\n\\n---\\n\\n# Using Idempotency Keys in APIs\\n\\nFor operations that are not naturally idempotent (e.g. financial transactions), APIs often use **idempotency keys** to enforce idempotency at the request level.\\n\\nA client generates a unique ID (often a UUID) and sends it with the request, typically in an `Idempotency-Key` header.\\n\\n## How It Works\\n\\n- **Server checks the key**: If the key was seen before, the server returns the stored response and does not execute the operation again.\\n- **New key**: If the key is new, the server processes the request, stores the result (and the key), and returns the result.\\n- **Key expiration**: Keys are often given a time-to-live (e.g. 24 hours) to limit storage and stale entries.\\n\\n### Example\\n\\nWhen charging a customer, the client includes:\\n\\n```\\nIdempotency-Key: abc123\\n```\\n\\nIf a network error causes a timeout and the client retries with the same key, the server recognizes `abc123` and returns the original charge response instead of creating a second charge.\\n\\nAs HackerNoon notes, **RFC 8594** defines this header: the client is responsible for unique key generation, and the server can optionally store a fingerprint of the request to detect duplicates.\\n\\nThis pattern is widely used in **payment APIs** (e.g., Stripe) and helps ensure \\"exactly-once\\" behavior on retries.\\n\\n### Key Best Practices\\n\\n- **Client-side**: Generate a unique idempotency key per operation. On retry, reuse the same key.\\n- **Server-side**: Check for existing key before processing. If found, return the earlier response; if not, perform the action and record the key with its outcome.\\n- **Design for idempotency**: Ensure the underlying operation is safe to repeat or that duplicates can be detected and ignored.\\n\\n---\\n\\n\\n\\n# Idempotent Database Operations\\n\\nIn databases, an **idempotent operation** is one that, when repeated, produces the same result as a single execution.\\n\\nA common idempotent pattern is the **UPSERT** (update-or-insert) operation. For example:\\n\\n```sql\\nINSERT ⦠ON CONFLICT UPDATE\\n```\\n\\nRunning this with the same values multiple times will not create duplicates.\\n\\n## Examples of Idempotent DB Operations\\n\\n- **Upserts**: In SQL and NoSQL, upsert commands ensure one-time insertion.\\n- **Fixed updates**: `SET status = \'active\'` is idempotent; repeating it doesnât change anything beyond the first update.\\n- **Idempotent deletes**: `DELETE FROM table WHERE id = X` is idempotent â once X is gone, repeating the delete does nothing.\\n- **Unique checks**: Before inserting, check for an existing key or use unique constraints (e.g., using a transaction ID to detect a repeated payment request).\\n- **Retry-safe transactions**: If a transaction fails and aborts, no partial changes are committed, so retrying does not cause double effects.\\n\\n> Cockroach Labs points out that some operations are ânaturally idempotentâ (like updating customer info) while others (like subtracting funds) are **not without safeguards**.\\n\\nBy using **upserts**, **unique constraints**, and **careful transaction design**, database writes can be made effectively idempotent.\\n\\n---\\n\\n\\n\\n# Idempotency in Distributed Systems\\n\\nIn **distributed systems**, unreliable networks and concurrent execution make idempotency crucial.\\n\\n### Example\\n\\nConsider an online payment: the client submits a charge but loses connection. The client retries, unsure if the first went through. Without idempotency, the user might be double-charged.\\n\\nDesigning the service to be idempotent **prevents such issues**.\\n\\n## Common Strategies\\n\\
1n- **Unique request identifiers** and **deduplication**.\\n- Each request carries a globally unique ID.\\n- The server or message processor sees a repeated ID and ignores it.\\n\\n### Distributed Message Queue\\n\\nThe consumer can track processed message IDs and skip any already handled.\\n\\nIf an operation is not naturally idempotent (like withdrawing money), the service can explicitly check for duplication.\\n","code":"var Component=(()=>{var p=Object.create;var r=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var w=(t,n)=>()=>(n||t((n={exports:{}}).exports,n),n.exports),y=(t,n)=>{for(var a in n)r(t,a,{get:n[a],enumerable:!0})},l=(t,n,a,s)=>{if(n&&typeof n==\\"object\\"||typeof n==\\"function\\")for(let i of u(n))!f.call(t,i)&&i!==a&&r(t,i,{get:()=>n[i],enumerable:!(s=m(n,i))||s.enumerable});return t};var k=(t,n,a)=>(a=t!=null?p(g(t)):{},l(n||!t||!t.__esModule?r(a,\\"default\\",{value:t,enumerable:!0}):a,t)),b=t=>l(r({},\\"__esModule\\",{value:!0}),t);var o=w((T,d)=>{d.exports=_jsx_runtime});var I={};y(I,{default:()=>h,frontmatter:()=>v});var e=k(o()),v={title:\\"Idempotency and Related Concepts\\",date:\\"2025-06-04\\",lastmod:\\"2025-06-04\\",tags:[\\"Technology\\"],draft:!1,images:\\"/static/images/blog/idempotency-and-related-concepts.png\\",summary:\\"Idempotency refers to a property of certain operations, especially in computing and mathematics, where performing the operation multiple times produces the same result as performing it just once. In other words, an idempotent operation can be executed multiple times without changing the outcome after the first application.\\",layout:\\"PostLayout\\",canonicalUrl:\\"https://blog.devity.in/technology/idempotency-and-related-concepts/\\"};function c(t){let n={a:\\"a\\",blockquote:\\"blockquote\\",code:\\"code\\",div:\\"div\\",h1:\\"h1\\",h2:\\"h2\\",h3:\\"h3\\",hr:\\"hr\\",li:\\"li\\",p:\\"p\\",path:\\"path\\",pre:\\"pre\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",ul:\\"ul\\",...t.components},{Image:a}=n;return a||x(\\"Image\\",!0),(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(n.div,{children:(0,e.jsx)(a,{alt:\\"Idempotent HTTP Methods in RESTful APIs\\",src:\\"/static/images/blog/idempotent-http-methods.png\\",width:\\"2790\\",height:\\"1900\\"})}),(0,e.jsxs)(n.h1,{className:\\"content-header\\",id:\\"idempotent-http-methods-in-restful-apis\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#idempotent-http-methods-in-restful-apis\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Idempotent HTTP Methods in RESTful APIs\\"]}),(0,e.jsxs)(n.p,{children:[\\"In RESTful APIs, \\",(0,e.jsx)(n.strong,{children:\\"idempotency\\"}),\\" ensures that making the same request multiple times has the same effect as making it once. In other words, repeated calls do not further change the server\\\\u2019s state.\\"]}),(0,e.jsx)(n.p,{children:\\"The MDN Web Docs define an idempotent HTTP method as one whose effect on the server of a single request is the same as for several identical requests. For example:\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"GET\\"}),\\" (read) is idempotent because fetching a resource repeatedly does not alter it.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"DELETE\\"}),\\" is idempotent because deleting a resource twice leaves it in the same \\\\u201Cdeleted\\\\u201D state (the first call succeeds; subsequent calls find nothing to delete).\\"]})]}),(0,e.jsxs)(n.p,{children:[\\"By contrast, \\",(0,e.jsx)(n.strong,{children:\\"POST\\"}),\\" usually creates new resources on each call, so it is \\",(0,e.jsx)(n.strong,{children:\\"not idempotent\\"}),\\".\\"]}),(0,e.jsxs)(n.p,{children:[\\"As noted by HackerNoon, the methods \\",(0,e.jsx)(n.code,{children:\\"GET\\"}),\\", \\",(0,e.jsx)(n.code,{children:\\"PUT\\"}),\\", \\",(0,e.jsx)(n.code,{children:\\"DELETE\\"}),\\", \\",(0,e.jsx)(n.code,{children:\\"HEAD\\"}),\\", \\",(0,e.jsx)(n.code,{children:\\"OPTIONS\\"}),\\", and \\",(0,e.jsx)(n.code,{children:\\"TRACE\\"}),\\" are idempotent, whereas \\",(0,e.jsx)(n.code,{children:\\"POST\\"}),\\" and \\",(0,e.jsx)(n.code,{children:\\"PATCH\\"}),\\" are not. In practice, this means clients can safely retry idempotent calls if they time out, without worrying about unintended side effects.\\"]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"summary-of-http-methods\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#summary-of-http-methods\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Summary of HTTP Methods\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"GET / HEAD / OPTIONS / TRACE\\"}),\\": Read-only requests that do not modify state. Repeating them returns (nearly) the same response and leaves the server unchanged.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"PUT\\"}),\\": Replaces or updates a resource. Issuing the same PUT repeatedly ends with the same final state (resource content).\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"DELETE\\"}),\\": Removes a resource. After the first successful delete, subsequent DELETEs do n
1othing new (the resource is already gone).\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"POST / PATCH\\"}),\\": Generally not idempotent. Each POST typically creates a new entity or has a distinct effect, so re-sending it will duplicate work.\\"]})]}),(0,e.jsxs)(n.p,{children:[\\"All \\",(0,e.jsx)(n.strong,{children:\\"safe HTTP methods\\"}),\\" (those that only read data) are by definition idempotent. PUT and DELETE are also idempotent, while POST is not.\\"]}),(0,e.jsx)(n.p,{children:\\"Understanding these differences helps design more reliable APIs and informs how clients should retry requests.\\"}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h1,{className:\\"content-header\\",id:\\"using-idempotency-keys-in-apis\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#using-idempotency-keys-in-apis\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Using Idempotency Keys in APIs\\"]}),(0,e.jsxs)(n.p,{children:[\\"For operations that are not naturally idempotent (e.g. financial transactions), APIs often use \\",(0,e.jsx)(n.strong,{children:\\"idempotency keys\\"}),\\" to enforce idempotency at the request level.\\"]}),(0,e.jsxs)(n.p,{children:[\\"A client generates a unique ID (often a UUID) and sends it with the request, typically in an \\",(0,e.jsx)(n.code,{children:\\"Idempotency-Key\\"}),\\" header.\\"]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"how-it-works\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#how-it-works\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"How It Works\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Server checks the key\\"}),\\": If the key was seen before, the server returns the stored response and does not execute the operation again.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"New key\\"}),\\": If the key is new, the server processes the request, stores the result (and the key), and returns the result.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Key expiration\\"}),\\": Keys are often given a time-to-live (e.g. 24 hours) to limit storage and stale entries.\\"]})]}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"example\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#example\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Example\\"]}),(0,e.jsx)(n.p,{children:\\"When charging a customer, the client includes:\\"}),(0,e.jsx)(n.pre,{className:\\"language-js\\",children:(0,e.jsx)(n.code,{className:\\"code-highlight language-js\\",children:(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token maybe-class-name\\",children:\\"Idempotency\\"}),(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"-\\"}),(0,e.jsx)(n.span,{className:\\"token maybe-class-name\\",children:\\"Key\\"}),(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\":\\"}),` abc123\\n`]})})}),(0,e.jsxs)(n.p,{children:[\\"If a network error causes a timeout and the client retries with the same key, the server recognizes \\",(0,e.jsx)(n.code,{children:\\"abc123\\"}),\\" and returns the original charge response instead of creating a second charge.\\"]}),(0,e.jsxs)(n.p,{children:[\\"As HackerNoon notes, \\",(0,e.jsx)(n.strong,{children:\\"RFC 8594\\"}),\\" defines this header: the client is responsible for unique key generation, and the server can optionally store a fingerprint of the request to detect duplicates.\\"]}),(0,e.jsxs)(n.p,{children:[\\"This pattern is widely used in \\",(0,e.jsx)(n.strong,{children:\\"payment APIs\\"}
1),\' (e.g., Stripe) and helps ensure \\"exactly-once\\" behavior on retries.\']}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"key-best-practices\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#key-best-practices\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Key Best Practices\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Client-side\\"}),\\": Generate a unique idempotency key per operation. On retry, reuse the same key.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Server-side\\"}),\\": Check for existing key before processing. If found, return the earlier response; if not, perform the action and record the key with its outcome.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Design for idempotency\\"}),\\": Ensure the underlying operation is safe to repeat or that duplicates can be detected and ignored.\\"]})]}),(0,e.jsx)(n.hr,{}),(0,e.jsx)(n.div,{children:(0,e.jsx)(a,{alt:\\"Idempotent Database Operations\\",src:\\"/static/images/blog/idempotent-database-operations.png\\",width:\\"2952\\",height:\\"2016\\"})}),(0,e.jsxs)(n.h1,{className:\\"content-header\\",id:\\"idempotent-database-operations\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#idempotent-database-operations\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Idempotent Database Operations\\"]}),(0,e.jsxs)(n.p,{children:[\\"In databases, an \\",(0,e.jsx)(n.strong,{children:\\"idempotent operation\\"}),\\" is one that, when repeated, produces the same result as a single execution.\\"]}),(0,e.jsxs)(n.p,{children:[\\"A common idempotent pattern is the \\",(0,e.jsx)(n.strong,{children:\\"UPSERT\\"}),\\" (update-or-insert) operation. For example:\\"]}),(0,e.jsx)(n.pre,{className:\\"language-sql\\",children:(0,e.jsx)(n.code,{className:\\"code-highlight language-sql\\",children:(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"INSERT\\"}),\\" \\\\u2026 \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"ON\\"}),\\" CONFLICT \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"UPDATE\\"}),`\\n`]})})}),(0,e.jsx)(n.p,{children:\\"Running this with the same values multiple times will not create duplicates.\\"}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"examples-of-idempotent-db-operations\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#examples-of-idempotent-db-operations\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Examples of Idempotent DB Operations\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Upserts\\"}),\\": In SQL and NoSQL, upsert commands ensure one-time insertion.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Fixed updates\\"}),\\": \\",(0,e.jsx)(n.code,{children:\\"SET status = \'active\'\\"}),\\" is idempotent; repeating it doesn\\\\u2019t change anything beyond the first update.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Idempotent deletes\\"}),\\": \\",(0,e.jsx)(n.code,{children:\\"DELETE FROM table WHERE id = X\\"}),\\" is idempotent \\\\u2013 once X is gone, repeating the delete does nothing.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Unique checks\\"}),\\": Before inserting, check for an existing key or use unique constraints (e.g., using a transaction ID to detect a repeated payment request).\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Retry-safe transactions\\"}),\\": If a transaction fails and aborts, no partial changes are committed, so retrying does not cause double effects.\\"]})]}),(0,e.jsx)(n.blockquote,{children:(0,e.jsxs)(n.p,{children:[\\"Cockroach Labs points out that some operations are \\\\u201Cnaturally idempotent\\\\u201D (like updating customer info) while others (like subtracting funds) are \\",(0,e.jsx)(n.strong,{children:\\"not without safeguards\\"}),\\".\\"]})}),(0,e.jsxs)(n.p,{children:[\\"By using \\",(0,e.jsx)(n.strong,{children:\\"upserts\\"}),\\", \\",(0,e.jsx)(n.strong,{children:\\"unique constraints\\"}),\\", and \\",(0,e.jsx)(n.strong,{children:\\"careful transaction design\\"}),\\", database writes can be made effectively idempotent.\\"]}),(0,e.jsx)(n.hr,{}),(0,e.jsx)(n.div,{children:(0,e.jsx)(a,{alt:\\"Idempotency in Distributed Systems\\",src:\\"/static/images/blog/idempotency-in-distributed-systems.png\\",width:\\"2808\\",height:\\"1728\\"})}),(0,e.jsxs)(n.h1,{className:\\"content-header\\",id:\\"idempotency-in-distributed-systems\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#idempotency-in-distributed-systems\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Idempotency in Distributed Systems\\"]}),(0,e.jsxs)(n.p,{children:[\\"In \\",(0,e.jsx)(n.strong,{children:\\"distributed systems\\"}),\\", unreliable networks and concurrent execution make idempotency crucial.\\"]}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"example-1\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#example-1\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Example\\"]}),(0,e.jsx)(n.p,{children:\\"Consider an online payment: the client submits a charge but loses connection. The client retries, unsure if the first went through. Without idempotency, the user might be double-charged.\\"}),(0,e.jsxs)(n.p,{children:[\\"Designing the service to be idempotent \\",(0,e.jsx)(n.strong,{children:\\"prevents such issues\\"}),\\".\\"]}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"common-strategies\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#common-strategies\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Common Strategies\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Unique request identifiers\\"}),\\" and \\",(0,e.jsx)(n.strong,{children:\\"deduplication\\"}),\\".\\"]}),(0,e.jsx)(n.li,{children:\\"Each request carries a globally unique ID.\\"}),(0,e.jsx)(n.li,{children:\\"The server or message processor sees a repeated ID and ignores it.\\"})]}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"distributed-message-queue\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#distributed-message-queue\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Distributed Message Queue\\"]}),(0,e.jsx)(n.p,{children:\\"The consumer can track processed message IDs and skip any already handled.\\"}),(0,e.jsx)(n.p,{children:\\"If an operation is not naturally idempotent (like withdrawing money), the service can explicitly check for duplication.\\"})]})}function h(t={}){let{wrapper:n}=t.components||{};return n?(0,e.jsx)(n,{...t,children:(0,e.jsx)(c,{...t})}):c(t)}function x(t,n){throw new Error(\\"Expected \\"+(n?\\"component\\":\\"object\\")+\\" `\\"+t+\\"` to be defined: you likely forgot to import, pass, or provide it.\\")}return b(I);})();\\n;return Component;"},"_id":"blog/technology/idempotency-and-related-concepts.mdx","_raw":{"sourceFilePath":"blog/technology/idempotency-and-related-concepts.mdx","sourceFileName":"idempotency-and-related-concepts.mdx","sourceFileDir":"blog/technology","contentType":"mdx","flattenedPath":"blog/technology/idempotency-and-related-concepts"},"type":"Blog","readingTime":{"text":"5 min read","minutes":4.51,"time":270600,"w
1ords":902},"slug":"technology/idempotency-and-related-concepts","path":"blog/technology/idempotency-and-related-concepts","filePath":"blog/technology/idempotency-and-related-concepts.mdx","toc":[{"value":"Idempotent HTTP Methods in RESTful APIs","url":"#idempotent-http-methods-in-restful-apis","depth":1},{"value":"Summary of HTTP Methods","url":"#summary-of-http-methods","depth":2},{"value":"Using Idempotency Keys in APIs","url":"#using-idempotency-keys-in-apis","depth":1},{"value":"How It Works","url":"#how-it-works-2","depth":2},{"value":"Example","url":"#example","depth":3},{"value":"Key Best Practices","url":"#key-best-practices","depth":3},{"value":"Idempotent Database Operations","url":"#idempotent-database-operations","depth":1},{"value":"Examples of Idempotent DB Operations","url":"#examples-of-idempotent-db-operations","depth":2},{"value":"Idempotency in Distributed Systems","url":"#idempotency-in-distributed-systems","depth":1},{"value":"Example","url":"#example-1","depth":3},{"value":"Common Strategies","url":"#common-strategies","depth":2},{"value":"Distributed Message Queue","url":"#distributed-message-queue","depth":3}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"Idempotency and Related Concepts","datePublished":"2025-06-04T00:00:00.000Z","dateModified":"2025-06-04T00:00:00.000Z","description":"Idempotency refers to a property of certain operations, especially in computing and mathematics, where performing the operation multiple times produces the same result as performing it just once. In other words, an idempotent operation can be executed multiple times without changing the outcome after the first application.","url":"https://www.devity.in/blog/technology/idempotency-and-related-concepts/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/blog/idempotency-and-related-concepts.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"Building a Semantic Search Engine with LangChain: A Step-by-Step Guide","date":"2025-06-08T00:00:00.000Z","tags":["Technology","LangChain","PostgreSQL","pgvector"],"keywords":[],"lastmod":"2025-06-08T00:00:00.000Z","draft":true,"summary":"Building a semantic search engine is a complex task that requires a deep understanding of natural language processing (NLP) and machine learning (ML).","images":"","layout":"PostLayout","canonicalUrl":"","faqs":[],"body":{"raw":"\\nLangChain is a flexible framework that makes it easy to build applications using LLMs, including semantic search engines. In this guide, you\'ll learn how to build a semantic search engine on top of PostgreSQL using LangChain and pgvector.\\n\\n---\\n\\n## \uD83E\uDDF1 Overview\\n\\nWe\'ll use:\\n\\n- **LangChain**: For orchestrating LLM pipelines\\n- **pgvector**: PostgreSQL extension for vector similarity search\\n- **Hugging Face Embeddings**: To convert text into embeddings\\n- **PostgreSQL**: As our structured data source and vector store\\n\\n---\\n\\n## \uD83D\uDCE6 Prerequisites\\n\\n1. Python ⥠3.8\\n2. A PostgreSQL database with data to search\\n3. Install `pgvector` in PostgreSQL:\\n\\n ```sql\\n CREATE EXTENSION IF NOT EXISTS vector;\\n ```\\n\\n4. Install required Python packages:\\n ```bash\\n pip install langchain langchain-community pgvector psycopg2-binary\\n pip install sentence-transformers\\n ```\\n\\n---\\n\\n## \uD83D\uDDC3ï¸ Step 1: Connect to PostgreSQL\\n\\nUse psycopg2 to connect to your PostgreSQL instance.\\n\\n```python\\nimport psycopg2\\n\\nconnection = psycopg2.connect(\\n dbname=\\"mydb\\",\\n user=\\"user\\",\\n password=\\"password\\",\\n host=\\"localhost\\",\\n port=5432\\n)\\n```\\n\\n---\\n\\n## \uD83E\uDDE0 Step 2: Generate Embeddings\\n\\nUse `sentence-transformers` to generate semantic embeddings.\\n\\n```python\\nfrom sentence_transformers import SentenceTransformer\\n\\nmodel = SentenceTransformer(\'all-MiniLM-L6-v2\')\\n\\ntexts = [\\"This is a semantic search example.\\", \\"Another document.\\"]\\nembeddings = model.encode(texts).tolist()\\n```\\n\\n---\\n\\n## \uD83D\uDCE5 Step 3: Store Embeddings in PostgreSQL (pgvector)\\n\\nCreate a table with a `vector` column and insert data.\\n\\n```sql\\nCREATE TABLE documents (\\n id SERIAL PRIMARY KEY,\\n content TEXT,\\n embedding vector(384)\\n);
1\\n```\\n\\n```python\\ncursor = connection.cursor()\\nfor text, emb in zip(texts, embeddings):\\n cursor.execute(\\n \\"INSERT INTO documents (content, embedding) VALUES (%s, %s)\\",\\n (text, emb)\\n )\\nconnection.commit()\\n```\\n\\n---\\n\\n## \uD83D\uDD0D Step 4: Query Similar Documents\\n\\nUse vector similarity with `pgvector`:\\n\\n```python\\nquery_text = \\"Find examples of semantic search\\"\\nquery_vector = model.encode([query_text])[0].tolist()\\n\\ncursor.execute(\\n \\"SELECT content FROM documents ORDER BY embedding <-> %s LIMIT 5\\",\\n (query_vector,)\\n)\\nresults = cursor.fetchall()\\nfor result in results:\\n print(result[0])\\n```\\n\\n---\\n\\n## \uD83D\uDD01 Optional: Add LLM for Summarization\\n\\nUse OpenAI or Ollama with LangChain for summarizing the results.\\n\\n```python\\nfrom langchain_community.llms import Ollama\\nfrom langchain.prompts import PromptTemplate\\nfrom langchain.chains import LLMChain\\n\\nllm = Ollama(model=\\"mistral\\")\\n\\nprompt = PromptTemplate.from_template(\\"Summarize these results:\\n{results}\\")\\nchain = LLMChain(llm=llm, prompt=prompt)\\n\\nresponse = chain.run(results=\\"\\n\\".join(r[0] for r in results))\\nprint(response)\\n```\\n\\n---\\n\\n## \uD83E\uDDF0 Useful Tips\\n\\n- Create an index on the vector column for faster queries:\\n\\n ```sql\\n CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);\\n ```\\n\\n- Normalize embeddings for better cosine similarity:\\n ```python\\n import numpy as np\\n def normalize(v): return v / np.linalg.norm(v)\\n ```\\n\\n---\\n\\n## \uD83D\uDE80 Conclusion\\n\\nYou\'ve now built a simple yet powerful semantic search engine using LangChain, pgvector, and Hugging Face embeddings. Extend it with:\\n\\n- A web interface (Streamlit/FastAPI)\\n- LangChain Retriever for full RAG pipelines\\n- LLM integration for natural language querying\\n\\n---\\n\\n## \uD83D\uDD17 Resources\\n\\n- [LangChain GitHub](https://github.com/langchain-ai/langchain)\\n- [pgvector GitHub](https://github.com/pgvector/pgvector)\\n- [Sentence Transformers](https://www.sbert.net/)\\n- [Ollama](https://ollama.com)\\n","code":"var Component=(()=>{var p=Object.create;var c=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var N=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var g=(a,n)=>()=>(n||a((n={exports:{}}).exports,n),n.exports),w=(a,n)=>{for(var s in n)c(a,s,{get:n[s],enumerable:!0})},i=(a,n,s,t)=>{if(n&&typeof n==\\"object\\"||typeof n==\\"function\\")for(let l of u(n))!k.call(a,l)&&l!==s&&c(a,l,{get:()=>n[l],enumerable:!(t=m(n,l))||t.enumerable});return a};var y=(a,n,s)=>(s=a!=null?p(N(a)):{},i(n||!a||!a.__esModule?c(s,\\"default\\",{value:a,enumerable:!0}):s,a)),f=a=>i(c({},\\"__esModule\\",{value:!0}),a);var o=g((L,r)=>{r.exports=_jsx_runtime});var x={};w(x,{default:()=>h,frontmatter:()=>v});var e=y(o()),v={title:\\"Building a Semantic Search Engine with LangChain: A Step-by-Step Guide\\",date:\\"2025-06-08\\",lastmod:\\"2025-06-08\\",tags:[\\"Technology\\",\\"LangChain\\",\\"PostgreSQL\\",\\"pgvector\\"],draft:!0,images:\\"\\",summary:\\"Building a semantic search engine is a complex task that requires a deep understanding of natural language processing (NLP) and machine learning (ML).\\",layout:\\"PostLayout\\",canonicalUrl:\\"\\"};function d(a){let n={a:\\"a\\",code:\\"code\\",h2:\\"h2\\",hr:\\"hr\\",li:\\"li\\",ol:\\"ol\\",p:\\"p\\",path:\\"path\\",pre:\\"pre\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",ul:\\"ul\\",...a.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(n.p,{children:\\"LangChain is a flexible framework that makes it easy to build applications using LLMs, including semantic search engines. In this guide, you\'ll learn how to build a semantic search engine on top of PostgreSQL using LangChain and pgvector.\\"}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-overview\\",children:[(0,e.jsx)(n.a,{href:\\"#-overview\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F9F1} Overview\\"]}),(0,e.jsx)(n.p,{children:\\"We\'ll use:\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"LangChain\\"}),\\": For orchestrating LLM pipelines\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"pgvector\\"}),\\": PostgreSQL extension for vector similarity search\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Hugging Face Embeddings\\"}),\\": To convert text into embeddings\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"PostgreSQL\\"}),\\": As our structured data source and vector store\\"]})]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-prerequisites\\",children:[(0,e.jsx)(n.a,{href:\\"#
1-prerequisites\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F4E6} Prerequisites\\"]}),(0,e.jsxs)(n.ol,{children:[(0,e.jsx)(n.li,{children:(0,e.jsx)(n.p,{children:\\"Python \\\\u2265 3.8\\"})}),(0,e.jsx)(n.li,{children:(0,e.jsx)(n.p,{children:\\"A PostgreSQL database with data to search\\"})}),(0,e.jsxs)(n.li,{children:[(0,e.jsxs)(n.p,{children:[\\"Install \\",(0,e.jsx)(n.code,{children:\\"pgvector\\"}),\\" in PostgreSQL:\\"]}),(0,e.jsx)(n.pre,{className:\\"language-sql\\",children:(0,e.jsx)(n.code,{className:\\"code-highlight language-sql\\",children:(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"CREATE\\"}),\\" EXTENSION \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"IF\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"NOT\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"EXISTS\\"}),\\" vector\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\";\\"}),`\\n`]})})})]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.p,{children:\\"Install required Python packages:\\"}),(0,e.jsx)(n.pre,{className:\\"language-bash\\",children:(0,e.jsxs)(n.code,{className:\\"code-highlight language-bash\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"pip \\",(0,e.jsx)(n.span,{className:\\"token function\\",children:\\"install\\"}),` langchain langchain-community pgvector psycopg2-binary\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"pip \\",(0,e.jsx)(n.span,{className:\\"token function\\",children:\\"install\\"}),` sentence-transformers\\n`]})]})})]})]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"\\\\uFE0F-step-1-connect-to-postgresql\\",children:[(0,e.jsx)(n.a,{href:\\"#\\\\uFE0F-step-1-connect-to-postgresql\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F5C3}\\\\uFE0F Step 1: Connect to PostgreSQL\\"]}),(0,e.jsx)(n.p,{children:\\"Use psycopg2 to connect to your PostgreSQL instance.\\"}),(0,e.jsx)(n.pre,{className:\\"language-python\\",children:(0,e.jsxs)(n.code,{className:\\"language-python code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"import\\"}),` psycopg2\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"connection \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" psycopg2\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"connect\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" dbname\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"mydb\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" user\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"user\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" password\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"password\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" host\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"localhost\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" port\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),(0,e.jsx)(n.span,{className:\\"token number\\",children:\\"5432\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]})]})}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-step-2-generate-embeddings\\",children:[(0,e.jsx)(n.a,{href:\\"#
1-step-2-generate-embeddings\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F9E0} Step 2: Generate Embeddings\\"]}),(0,e.jsxs)(n.p,{children:[\\"Use \\",(0,e.jsx)(n.code,{children:\\"sentence-transformers\\"}),\\" to generate semantic embeddings.\\"]}),(0,e.jsx)(n.pre,{className:\\"language-python\\",children:(0,e.jsxs)(n.code,{className:\\"language-python code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"from\\"}),\\" sentence_transformers \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"import\\"}),` SentenceTransformer\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"model \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" SentenceTransformer\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token string\\",children:\\"\'all-MiniLM-L6-v2\'\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"texts \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"[\\"}),(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"This is a semantic search example.\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"Another document.\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"]\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"embeddings \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" model\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"encode\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"texts\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"tolist\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]})]})}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-step-3-store-embeddings-in-postgresql-pgvector\\",children:[(0,e.jsx)(n.a,{href:\\"#-step-3-store-embeddings-in-postgresql-pgvector\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F4E5} Step 3: Store Embeddings in PostgreSQL (pgvector)\\"]}),(0,e.jsxs)(n.p,{children:[\\"Create a table with a \\",(0,e.jsx)(n.code,{children:\\"vector\\"}),\\" column and insert data.\\"]}),(0,e.jsx)(n.pre,{className:\\"language-sql\\",children:(0,e.jsxs)(n.code,{className:\\"code-highlight language-sql\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"CREATE\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"TABLE\\"}),\\" documents \\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" id \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"SERIAL\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"PRIMARY\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"KEY\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" content \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"TEXT\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" embedding vector\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token number\\",children:\\"384\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\";\\"}),`\\n`]})]})}),(0,e.jsx)(n.pre,{className:\\"language-python\\",children:(0,e.jsxs)(n.code,{className:\\"language-python code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"cursor \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" connection\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"cursor\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"for\\"}),\\" text\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),\\" emb \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"in\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token builtin\\",children:\\"zip\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"texts\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),\\" embeddings\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\":\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" cursor\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"execute\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"INSERT INTO documents (content, embedding) VALUES (%s, %s)\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"text\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),\\" emb\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"connection\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"commit\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]})]})}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-step-4-query-similar-documents\\",children:[(0,e.jsx)(n.a,{href:\\"#
1-step-4-query-similar-documents\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F50D} Step 4: Query Similar Documents\\"]}),(0,e.jsxs)(n.p,{children:[\\"Use vector similarity with \\",(0,e.jsx)(n.code,{children:\\"pgvector\\"}),\\":\\"]}),(0,e.jsx)(n.pre,{className:\\"language-python\\",children:(0,e.jsxs)(n.code,{className:\\"language-python code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"query_text \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"Find examples of semantic search\\"\'}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"query_vector \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" model\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"encode\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"[\\"}),\\"query_text\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"]\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"[\\"}),(0,e.jsx)(n.span,{className:\\"token number\\",children:\\"0\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"]\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"tolist\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"cursor\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"execute\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"SELECT content FROM documents ORDER BY embedding <-> %s LIMIT 5\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"query_vector\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"results \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" cursor\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"fetchall\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"for\\"}),\\" result \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"in\\"}),\\" results\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\":\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"print\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"result\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"[\\"}),(0,e.jsx)(n.span,{className:\\"token number\\",children:\\"0\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"]\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]})]})}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-optional-add-llm-for-summarization\\",children:[(0,e.jsx)(n.a,{href:\\"#
1-optional-add-llm-for-summarization\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F501} Optional: Add LLM for Summarization\\"]}),(0,e.jsx)(n.p,{children:\\"Use OpenAI or Ollama with LangChain for summarizing the results.\\"}),(0,e.jsx)(n.pre,{className:\\"language-python\\",children:(0,e.jsxs)(n.code,{className:\\"language-python code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"from\\"}),\\" langchain_community\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"llms \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"import\\"}),` Ollama\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"from\\"}),\\" langchain\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"prompts \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"import\\"}),` PromptTemplate\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"from\\"}),\\" langchain\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"chains \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"import\\"}),` LLMChain\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"llm \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" Ollama\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"model\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"mistral\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"prompt \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" PromptTemplate\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"from_template\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\'\\"Summarize these results\',(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\":\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"{\\"}),\\"results\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"}\\"}),\'\\"\',(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"chain \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" LLMChain\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"llm\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\"llm\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),\\" prompt\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\"prompt\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"response \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" chain\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"run\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"results\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),`\\"\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\'\\"\',(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"join\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"r\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"[\\"}),(0,e.jsx)(n.span,{className:\\"token number\\",children:\\"0\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"]\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"for\\"}),\\" r \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"in\\"}),\\" results\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"print\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"response\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]})]})}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-useful-tips\\",children:[(0,e.jsx)(n.a,{href:\\"#
1-useful-tips\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F9F0} Useful Tips\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.p,{children:\\"Create an index on the vector column for faster queries:\\"}),(0,e.jsx)(n.pre,{className:\\"language-sql\\",children:(0,e.jsx)(n.code,{className:\\"code-highlight language-sql\\",children:(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"CREATE\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"INDEX\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"ON\\"}),\\" documents \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"USING\\"}),\\" ivfflat \\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"embedding vector_cosine_ops\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"WITH\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"lists \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token number\\",children:\\"100\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\";\\"}),`\\n`]})})})]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.p,{children:\\"Normalize embeddings for better cosine similarity:\\"}),(0,e.jsx)(n.pre,{className:\\"language-python\\",children:(0,e.jsxs)(n.code,{className:\\"language-python code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"import\\"}),\\" numpy \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"as\\"}),` np\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"def\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token function\\",children:\\"normalize\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"v\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\":\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"return\\"}),\\" v \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"/\\"}),\\" np\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"linalg\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"norm\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"v\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]})]})})]})]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-conclusion\\",children:[(0,e.jsx)(n.a,{href:\\"#-conclusion\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F680} Conclusion\\"]}),(0,e.jsx)(n.p,{children:\\"You\'ve now built a simple yet powerful semantic search engine using LangChain, pgvector, and Hugging Face embeddings. Extend it with:\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsx)(n.li,{children:\\"A web interface (Streamlit/FastAPI)\\"}),(0,e.jsx)(n.li,{children:\\"LangChain Retriever for full RAG pipelines\\"}),(0,e.jsx)(n.li,{children:\\"LLM integration for natural language querying\\"})]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-resources\\",children:[(0,e.jsx)(n.a,{href:\\"#
1-resources\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F517} Resources\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsx)(n.li,{children:(0,e.jsx)(n.a,{href:\\"https://github.com/langchain-ai/langchain\\",children:\\"LangChain GitHub\\"})}),(0,e.jsx)(n.li,{children:(0,e.jsx)(n.a,{href:\\"https://github.com/pgvector/pgvector\\",children:\\"pgvector GitHub\\"})}),(0,e.jsx)(n.li,{children:(0,e.jsx)(n.a,{href:\\"https://www.sbert.net/\\",children:\\"Sentence Transformers\\"})}),(0,e.jsx)(n.li,{children:(0,e.jsx)(n.a,{href:\\"https://ollama.com\\",children:\\"Ollama\\"})})]})]})}function h(a={}){let{wrapper:n}=a.components||{};return n?(0,e.jsx)(n,{...a,children:(0,e.jsx)(d,{...a})}):d(a)}return f(x);})();\\n;return Component;"},"_id":"blog/technology/langchain-semantic-search-guide.mdx","_raw":{"sourceFilePath":"blog/technology/langchain-semantic-search-guide.mdx","sourceFileName":"langchain-semantic-search-guide.mdx","sourceFileDir":"blog/technology","contentType":"mdx","flattenedPath":"blog/technology/langchain-semantic-search-guide"},"type":"Blog","readingTime":{"text":"3 min read","minutes":2.265,"time":135900,"words":453},"slug":"technology/langchain-semantic-search-guide","path":"blog/technology/langchain-semantic-search-guide","filePath":"blog/technology/langchain-semantic-search-guide.mdx","toc":[{"value":"\uD83E\uDDF1 Overview","url":"#-overview","depth":2},{"value":"\uD83D\uDCE6 Prerequisites","url":"#-prerequisites","depth":2},{"value":"\uD83D\uDDC3ï¸ Step 1: Connect to PostgreSQL","url":"#ï¸-step-1-connect-to-postgresql","depth":2},{"value":"\uD83E\uDDE0 Step 2: Generate Embeddings","url":"#-step-2-generate-embeddings","depth":2},{"value":"\uD83D\uDCE5 Step 3: Store Embeddings in PostgreSQL (pgvector)","url":"#-step-3-store-embeddings-in-postgresql-pgvector","depth":2},{"value":"\uD83D\uDD0D Step 4: Query Similar Documents","url":"#-step-4-query-similar-documents","depth":2},{"value":"\uD83D\uDD01 Optional: Add LLM for Summarization","url":"#-optional-add-llm-for-summarization","depth":2},{"value":"\uD83E\uDDF0 Useful Tips","url":"#-useful-tips","depth":2},{"value":"\uD83D\uDE80 Conclusion","url":"#-conclusion","depth":2},{"value":"\uD83D\uDD17 Resources","url":"#-resources","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"Building a Semantic Search Engine with LangChain: A Step-by-Step Guide","datePublished":"2025-06-08T00:00:00.000Z","dateModified":"2025-06-08T00:00:00.000Z","description":"Building a semantic search engine is a complex task that requires a deep understanding of natural language processing (NLP) and machine learning (ML).","url":"https://www.devity.in/blog/technology/langchain-semantic-search-guide/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/devity-blog.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"Building a Semantic Search Engine with LlamaIndex : A Step-by-Step Guide","date":"2025-06-08T00:00:00.000Z","tags":["Technology","LlamaIndex","PostgreSQL","pgvector"],"keywords":[],"lastmod":"2025-06-08T00:00:00.000Z","draft":true,"summary":"Building a semantic search engine is a complex task that requires a deep understanding of natural language processing (NLP) and machine learning (ML).","images":"","layout":"PostLayout","canonicalUrl":"","faqs":[],"body":{"raw":"\\n\\n\\nSemantic search enables understanding of meaning, not just keywords. In this guide, we\'ll walk through building a semantic search engine using **LlamaIndex**, **PostgreSQL**, and **pgvector** â powered by open-source LLMs and embeddings.\\n\\n---\\n\\n## \uD83E\uDDF1 Overview\\n\\
1nWe\'ll use:\\n\\n- **LlamaIndex**: To ingest and index data from PostgreSQL\\n- **pgvector**: PostgreSQL extension for vector similarity search\\n- **Hugging Face Embeddings**: For local, open-source text embedding\\n- **Optional**: Use OpenAI or Ollama/Mistral for generation\\n\\n---\\n\\n## \uD83D\uDCE6 Prerequisites\\n\\n1. Python ⥠3.8\\n2. A PostgreSQL database with your content\\n3. Install `pgvector` extension in your DB:\\n\\n ```sql\\n CREATE EXTENSION IF NOT EXISTS vector;\\n ```\\n\\n4. Install required Python packages:\\n ```bash\\n pip install llama-index\\n pip install llama-index-llms-ollama # or llama-index-llms-openai\\n pip install llama-index-vector-stores-postgres\\n pip install llama-index-embeddings-huggingface\\n ```\\n\\n---\\n\\n## \uD83D\uDDC3ï¸ Step 1: Connect to Your PostgreSQL Database\\n\\nUse LlamaIndex\'s `SQLDatabaseReader` to load data.\\n\\n```python\\nfrom llama_index.readers.database import SQLDatabaseReader\\n\\ndb_uri = \\"postgresql://user:password@localhost:5432/mydb\\"\\nreader = SQLDatabaseReader(uri=db_uri, include_tables=[\\"articles\\"])\\ndocuments = reader.load_data()\\n```\\n\\n---\\n\\n## \uD83E\uDDE0 Step 2: Generate Embeddings\\n\\nWe\'ll use Hugging Face\'s `BAAI/bge-small-en` for semantic embeddings.\\n\\n```python\\nfrom llama_index.embeddings import HuggingFaceEmbedding\\n\\nembed_model = HuggingFaceEmbedding(model_name=\\"BAAI/bge-small-en\\")\\n```\\n\\n---\\n\\n## \uD83D\uDCE5 Step 3: Store Embeddings in pgvector\\n\\nCreate a vector store pointing to your PostgreSQL DB.\\n\\n```python\\nfrom llama_index.vector_stores.postgres import PGVectorStore\\n\\nvector_store = PGVectorStore(\\n connection_string=db_uri,\\n table_name=\\"vector_index\\",\\n embed_dim=384, # Dimension of BGE-small embeddings\\n)\\n```\\n\\n---\\n\\n## \uD83D\uDCDA Step 4: Build the Index\\n\\nNow index the documents with your embedding model and vector store.\\n\\n```python\\nfrom llama_index import VectorStoreIndex, ServiceContext\\n\\nservice_context = ServiceContext.from_defaults(embed_model=embed_model)\\n\\nindex = VectorStoreIndex.from_documents(\\n documents,\\n service_context=service_context,\\n vector_store=vector_store\\n)\\n```\\n\\n---\\n\\n## \uD83D\uDD0D Step 5: Query the Search Engine\\n\\nCreate a query engine and start searching.\\n\\n```python\\nquery_engine = index.as_query_engine()\\n\\nresponse = query_engine.query(\\"What is semantic search?\\")\\nprint(response)\\n```\\n\\n---\\n\\n## \uD83E\uDDEA Sample Output\\n\\n```\\nSemantic search refers to searching for content based on meaning, not just keywords. For example...\\n```\\n\\n---\\n\\n## \uD83D\uDD01 Optional: Use an LLM for Generation\\n\\nYou can replace the default response generator with OpenAI, Ollama, or any custom LLM.\\n\\n```python\\nfrom llama_index.llms import Ollama\\n\\nllm = Ollama(model=\\"mistral\\")\\nservice_context = ServiceContext.from_defaults(embed_model=embed_model, llm=llm)\\n```\\n\\n---\\n\\n## \uD83E\uDDF0 Useful Tips\\n\\n- Run pgvector similarity queries manually:\\n\\n ```sql\\n SELECT content\\n FROM vector_index\\n ORDER BY embedding <-> \'[embedding values]\'\\n LIMIT 5;\\n ```\\n\\n- You can chunk large fields before embedding using LlamaIndexâs `TextSplitter`.\\n\\n---\\n\\n## \uD83D\uDE80 Conclusion\\n\\nWith just a few lines of code, you\'ve built a powerful semantic search engine over PostgreSQL using LlamaIndex and pgvector. You can extend it by adding:\\n\\n- Web UI (Streamlit, Next.js)\\n- RAG pipelines\\n- API endpoints (FastAPI)\\n\\n---\\n\\n## \uD83D\uDD17 Resources\\n\\n- [LlamaIndex GitHub](https://github.com/jerryjliu/llama_index)\\n- [pgvector GitHub](https://github.com/pgvector/pgvector)\\n- [Hugging Face BGE Models](https://huggingface.co/BAAI/bge-small-en)\\n- [Ollama](https://ollama.com)\\n","code":"var Component=(()=>{var p=Object.create;var c=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,N=Object.prototype.hasOwnProperty;var k=(a,n)=>()=>(n||a((n={exports:{}}
1).exports,n),n.exports),w=(a,n)=>{for(var l in n)c(a,l,{get:n[l],enumerable:!0})},i=(a,n,l,r)=>{if(n&&typeof n==\\"object\\"||typeof n==\\"function\\")for(let s of u(n))!N.call(a,s)&&s!==l&&c(a,s,{get:()=>n[s],enumerable:!(r=m(n,s))||r.enumerable});return a};var x=(a,n,l)=>(l=a!=null?p(g(a)):{},i(n||!a||!a.__esModule?c(l,\\"default\\",{value:a,enumerable:!0}):l,a)),b=a=>i(c({},\\"__esModule\\",{value:!0}),a);var o=k((_,t)=>{t.exports=_jsx_runtime});var f={};w(f,{default:()=>h,frontmatter:()=>v});var e=x(o()),v={title:\\"Building a Semantic Search Engine with LlamaIndex : A Step-by-Step Guide\\",date:\\"2025-06-08\\",lastmod:\\"2025-06-08\\",tags:[\\"Technology\\",\\"LlamaIndex\\",\\"PostgreSQL\\",\\"pgvector\\"],draft:!0,images:\\"\\",summary:\\"Building a semantic search engine is a complex task that requires a deep understanding of natural language processing (NLP) and machine learning (ML).\\",layout:\\"PostLayout\\",canonicalUrl:\\"\\"};function d(a){let n={a:\\"a\\",code:\\"code\\",h2:\\"h2\\",hr:\\"hr\\",img:\\"img\\",li:\\"li\\",ol:\\"ol\\",p:\\"p\\",path:\\"path\\",pre:\\"pre\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",ul:\\"ul\\",...a.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(n.p,{children:(0,e.jsx)(n.img,{alt:\\"Building a Semantic Search Engine\\",src:\\"/static/images/blog/building-semantic-search-engine.png\\"})}),(0,e.jsxs)(n.p,{children:[\\"Semantic search enables understanding of meaning, not just keywords. In this guide, we\'ll walk through building a semantic search engine using \\",(0,e.jsx)(n.strong,{children:\\"LlamaIndex\\"}),\\", \\",(0,e.jsx)(n.strong,{children:\\"PostgreSQL\\"}),\\", and \\",(0,e.jsx)(n.strong,{children:\\"pgvector\\"}),\\" \\\\u2014 powered by open-source LLMs and embeddings.\\"]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-overview\\",children:[(0,e.jsx)(n.a,{href:\\"#-overview\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F9F1} Overview\\"]}),(0,e.jsx)(n.p,{children:\\"We\'ll use:\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"LlamaIndex\\"}),\\": To ingest and index data from PostgreSQL\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"pgvector\\"}),\\": PostgreSQL extension for vector similarity search\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Hugging Face Embeddings\\"}),\\": For local, open-source text embedding\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Optional\\"}),\\": Use OpenAI or Ollama/Mistral for generation\\"]})]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-prerequisites\\",children:[(0,e.jsx)(n.a,{href:\\"#-prerequisites\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F4E6} Prerequisites\\"]}),(0,e.jsxs)(n.ol,{children:[(0,e.jsx)(n.li,{children:(0,e.jsx)(n.p,{children:\\"Python \\\\u2265 3.8\\"})}),(0,e.jsx)(n.li,{children:(0,e.jsx)(n.p,{children:\\"A PostgreSQL database with your content\\"})}),(0,e.jsxs)(n.li,{children:[(0,e.jsxs)(n.p,{children:[\\"Install \\",(0,e.jsx)(n.code,{children:\\"pgvector\\"}),\\" extension in your DB:\\"]}),(0,e.jsx)(n.pre,{className:\\"language-sql\\",children:(0,e.jsx)(n.code,{className:\\"code-highlight language-sql\\",children:(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"CREATE\\"}),\\" EXTENSION \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"IF\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"NOT\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"EXISTS\\"}),\\" vector\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\";\\"}),`\\n`]})})})]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.p,{children:\\"Install required Python packages:\\"}),(0,e.jsx)(n.pre,{className:\\"language-bash\\",children:(0,e.jsxs)(n.code,{className:\\"code-highlight language-bash\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"pip \\",(0,e.jsx)(n.span,{className:\\"token function\\",children:\\"install\\"}),` llama-index\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"pip \\",(0,e.jsx)(n.span,{className:\\"token function\\",children:\\"install\\"}),\\" llama-index-llms-ollama \\",(0,e.jsx)(n.span,{className:\\"token comment\\",children:\\"# or llama-index-llms-openai\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"pip \\",(0,e.jsx)(n.span,{className:\\"token function\\",children:\\"install\\"}),` llama-index-vector-stores-postgres\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"pip \\",(0,e.jsx)(n.span,{className:\\"token function\\",children:\\"install\\"}),` llama-index-embeddings-huggingface\\n`]})]})})]})]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"\\\\uFE0F-step-1-connect-to-your-postgresql-database\\",children:[(0,e.jsx)(n.a,{href:\\"#\\\\uFE0F-step-1-connect-to-your-postgresql-database\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F5C3}\\\\uFE0F Step 1: Connect to Your PostgreSQL Database\\"]}),(0,e.jsxs)(n.p,{children:[\\"Use LlamaIndex\'s \\",(0,e.jsx)(n.code,{children:\\"SQLDatabaseReader\\"}),\\" to load data.\\"]}),(0,e.jsx)(n.pre,{className:\\"language-python\\",children:(0,e.jsxs)(n.code,{className:\\"language-python code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"from\\"}),\\" llama_index\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"readers\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"database \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"import\\"}),` SQLDatabaseReader\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"db_uri \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"postgresql://user:password@localhost:5432/mydb\\"\'}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"reader \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" SQLDatabaseReader\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"uri\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\"db_uri\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),\\" include_tables\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"[\\"}),(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"articles\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"]\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"documents \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" reader\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"load_data\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]})]})}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-step-2-generate-embeddings\\",children:[(0,e.jsx)(n.a,{href:\\"#
1-step-2-generate-embeddings\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F9E0} Step 2: Generate Embeddings\\"]}),(0,e.jsxs)(n.p,{children:[\\"We\'ll use Hugging Face\'s \\",(0,e.jsx)(n.code,{children:\\"BAAI/bge-small-en\\"}),\\" for semantic embeddings.\\"]}),(0,e.jsx)(n.pre,{className:\\"language-python\\",children:(0,e.jsxs)(n.code,{className:\\"language-python code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"from\\"}),\\" llama_index\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"embeddings \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"import\\"}),` HuggingFaceEmbedding\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"embed_model \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" HuggingFaceEmbedding\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"model_name\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"BAAI/bge-small-en\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]})]})}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-step-3-store-embeddings-in-pgvector\\",children:[(0,e.jsx)(n.a,{href:\\"#-step-3-store-embeddings-in-pgvector\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F4E5} Step 3: Store Embeddings in pgvector\\"]}),(0,e.jsx)(n.p,{children:\\"Create a vector store pointing to your PostgreSQL DB.\\"}),(0,e.jsx)(n.pre,{className:\\"language-python\\",children:(0,e.jsxs)(n.code,{className:\\"language-python code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"from\\"}),\\" llama_index\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"vector_stores\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"postgres \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"import\\"}),` PGVectorStore\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"vector_store \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" PGVectorStore\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" connection_string\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\"db_uri\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" table_name\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"vector_index\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" embed_dim\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),(0,e.jsx)(n.span,{className:\\"token number\\",children:\\"384\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token comment\\",children:\\"# Dimension of BGE-small embeddings\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]})]})}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-step-4-build-the-index\\",children:[(0,e.jsx)(n.a,{href:\\"#
1-step-4-build-the-index\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F4DA} Step 4: Build the Index\\"]}),(0,e.jsx)(n.p,{children:\\"Now index the documents with your embedding model and vector store.\\"}),(0,e.jsx)(n.pre,{className:\\"language-python\\",children:(0,e.jsxs)(n.code,{className:\\"language-python code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"from\\"}),\\" llama_index \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"import\\"}),\\" VectorStoreIndex\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),` ServiceContext\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"service_context \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" ServiceContext\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"from_defaults\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"embed_model\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\"embed_model\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"index \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" VectorStoreIndex\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"from_documents\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" documents\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" service_context\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\"service_context\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" vector_store\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),`vector_store\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]})]})}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-step-5-query-the-search-engine\\",children:[(0,e.jsx)(n.a,{href:\\"#-step-5-query-the-search-engine\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F50D} Step 5: Query the Search Engine\\"]}),(0,e.jsx)(n.p,{children:\\"Create a query engine and start searching.\\"}),(0,e.jsx)(n.pre,{className:\\"language-python\\",children:(0,e.jsxs)(n.code,{className:\\"language-python code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"query_engine \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" index\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"as_query_engine\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"response \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" query_engine\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"query\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"What is semantic search?\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"print\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"response\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]})]})}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-sample-output\\",children:[(0,e.jsx)(n.a,{href:\\"#
1-sample-output\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F9EA} Sample Output\\"]}),(0,e.jsx)(n.pre,{className:\\"language-js\\",children:(0,e.jsx)(n.code,{className:\\"code-highlight language-js\\",children:(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token maybe-class-name\\",children:\\"Semantic\\"}),\\" search refers to searching \\",(0,e.jsx)(n.span,{className:\\"token keyword control-flow\\",children:\\"for\\"}),\\" content based on meaning\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),\\" not just keywords\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token property-access\\",children:(0,e.jsx)(n.span,{className:\\"token maybe-class-name\\",children:\\"For\\"})}),\\" example\\",(0,e.jsx)(n.span,{className:\\"token operator spread\\",children:\\"...\\"}),`\\n`]})})}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-optional-use-an-llm-for-generation\\",children:[(0,e.jsx)(n.a,{href:\\"#-optional-use-an-llm-for-generation\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F501} Optional: Use an LLM for Generation\\"]}),(0,e.jsx)(n.p,{children:\\"You can replace the default response generator with OpenAI, Ollama, or any custom LLM.\\"}),(0,e.jsx)(n.pre,{className:\\"language-python\\",children:(0,e.jsxs)(n.code,{className:\\"language-python code-highlight\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"from\\"}),\\" llama_index\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"llms \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"import\\"}),` Ollama\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"llm \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" Ollama\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"model\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),(0,e.jsx)(n.span,{className:\\"token string\\",children:\'\\"mistral\\"\'}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\"service_context \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" ServiceContext\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),\\"from_defaults\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"embed_model\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\"embed_model\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),\\" llm\\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\"llm\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]})]})}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-useful-tips\\",children:[(0,e.jsx)(n.a,{href:\\"#
1-useful-tips\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F9F0} Useful Tips\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.p,{children:\\"Run pgvector similarity queries manually:\\"}),(0,e.jsx)(n.pre,{className:\\"language-sql\\",children:(0,e.jsxs)(n.code,{className:\\"code-highlight language-sql\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"SELECT\\"}),` content\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"FROM\\"}),` vector_index\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"ORDER\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"BY\\"}),\\" embedding \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"<\\"}),(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"-\\"}),(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\">\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token string\\",children:\\"\'[embedding values]\'\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"LIMIT\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token number\\",children:\\"5\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\";\\"}),`\\n`]})]})})]}),(0,e.jsx)(n.li,{children:(0,e.jsxs)(n.p,{children:[\\"You can chunk large fields before embedding using LlamaIndex\\\\u2019s \\",(0,e.jsx)(n.code,{children:\\"TextSplitter\\"}),\\".\\"]})})]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-conclusion\\",children:[(0,e.jsx)(n.a,{href:\\"#-conclusion\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F680} Conclusion\\"]}),(0,e.jsx)(n.p,{children:\\"With just a few lines of code, you\'ve built a powerful semantic search engine over PostgreSQL using LlamaIndex and pgvector. You can extend it by adding:\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsx)(n.li,{children:\\"Web UI (Streamlit, Next.js)\\"}),(0,e.jsx)(n.li,{children:\\"RAG pipelines\\"}),(0,e.jsx)(n.li,{children:\\"API endpoints (FastAPI)\\"})]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"-resources\\",children:[(0,e.jsx)(n.a,{href:\\"#-resources\\",\\"aria-hidden\\":\\"true\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"\\\\u{1F517} Resources\\"]}),(0,e.jsxs)(n.ul,{children:[(0,e.jsx)(n.li,{children:(0,e.jsx)(n.a,{href:\\"https://github.com/jerryjliu/llama_index\\",children:\\"LlamaIndex GitHub\\"})}),(0,e.jsx)(n.li,{children:(0,e.jsx)(n.a,{href:\\"https://github.com/pgvector/pgvector\\",children:\\"pgvector GitHub\\"})}),(0,e.jsx)(n.li,{children:(0,e.jsx)(n.a,{href:\\"https://huggingface.co/BAAI/bge-small-en\\",children:\\"Hugging Face BGE Models\\"})}),(0,e.jsx)(n.li,{children:(0,e.jsx)(n.a,{href:\\"https://ollama.com\\",children:\\"Ollama\\"})})]})]})}function h(a={}){let{wrapper:n}=a.components||{};return n?(0,e.jsx)(n,{...a,children:(0,e.jsx)(d,{...a})}):d(a)}return b(f);})();\\n;return Component;"},"_id":"blog/technology/llmaindex-semantic-search-guide.mdx","_raw":{"sourceFilePath":"blog/technology/llmaindex-semantic-search-guide.mdx","sourceFileName":"llmaindex-semantic-search-guide.mdx","sourceFileDir":"blog/technology","contentType":"mdx","flattenedPath":"blog/technology/llmaindex-semantic-search-guide"},"type":"Blog","readingTime":{"text":"3 min read","minutes":2.19,"time":131400,"words":438},"slug":"technology/llmaindex-semantic-search-guide","path":"blog/technology/llmaindex-semantic-search-guide","filePath":"blog/technology/llmaindex-semantic-search-guide.mdx","toc":[{"value":"\uD83E\uDDF1 Overview","url":"#-overview-1","depth":2},{"value":"\uD83D\uDCE6 Prerequisites","url":"#-prerequisites-1","depth":2},{"value":"\uD83D\uDDC3ï¸ Step 1: Connect to Your PostgreSQL Database","url":"#ï¸-step-1-connect-to-your-postgresql-database","depth":2},{"value":"\uD83E\uDDE0 Step 2: Generate Embeddings","url":"#-step-2-generate-embeddings-1","depth":2},{"value":"\uD83D\uDCE5 Step 3: Store Embeddings in pgvector","url":"#-step-3-store-embeddings-in-pgvector","depth":2},{"value":"\uD83D\uDCDA Step 4: Build the Index","url":"#-step-4-build-the-index","depth":2},{"value":"\uD83D\uDD0D Step 5: Query the Search Engine","url":"#-step-5-query-the-search-engine","depth":2},{"value":"\uD83E\uDDEA Sample Output","url":"#-sample-output","depth":2},{"value":"\uD83D\uDD01 Optional: Use an LLM for Generation","url":"#-optional-use-an-llm-for-generation","depth":2},{"value":"\uD83E\uDDF0 Useful Tips","url":"#-useful-tips-1","depth":2},{"value":"\uD83D\uDE80 Conclusion","url":"#-conclusion-1","depth":2},{"value":"\uD83D\uDD17 Resources","url":"#-resources-1","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"Building a Semantic Search Engine with LlamaIndex : A Step-by-Step Guide","datePublished":"2025-06-08T00:00:00.000Z","dateModified":"2025-06-08T00:00:00.000Z","description":"Building a semantic search engine is a complex task that requires a deep understanding of natural language processing (NLP) and machine learning (ML).","url":"https://www.devity.in/blog/technology/llmaindex-semantic-search-guide/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/devity-blog.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"Building Modular Mobile Experiences with React Native and Re.Pack","date":"2026-01-23T00:00:00.000Z","tags":["Technology"],"keywords":[],"lastmod":"2026-01-23T00:00:00.000Z","draft":false,"summary":"How React Native and Re.Pack enable modular Super App architecture with OTA updates, smaller downloads, and team-friendly scaling.","images":"/static/images/blog/modular-mobile-experiance.png","layout":"PostLayout","canonicalUrl":"","faqs":[],"body":{"raw":"\\nIn today\'s fast-paced mobile world, user expectations are higher than ever. Apps need to be fast, small, and constantly evolving. But what if your app is a sprawling monolith with dozens of features, leading to slow load times, bloated download sizes, and a glacial update cycle dictated by app store reviews?\\n\\nEnter the Super App Architectureâa paradigm shift that\'s transforming how we build and deploy large-scale mobile applications. This post dives deep into how you can leverage React Native with Re.Pack to create a modular, dynamic, and future-proof mobile ecosystem, tackling the common pain points head-on.\\n\\n## The Problem: When Your App Becomes a Monolith Monster\\n\\nImagine your app as a single, enormous house. Every new feature adds a new room, a new floor, or even an entire wing. Over time, this monolithic structure leads to several critical issues:\\n\\n- Bloated initial download size: Users are hesitant to download large apps. A massive initial download leads to abandonment, especially in regions with limited data or storage.\\n\\n- Slow updates and iteration: Every bug fix, every minor UI tweak, and every new feature requires a full app store submission and review process. This can take days, delaying crucial updates and slowing down your development velocity.\\n\\n- Increased build times: As your codebase grows, so do your build times, impacting developer productivity.\\n\\n- Team scaling challenges: Large, interconnected codebase
1s become difficult for multiple independent teams to manage simultaneously without stepping on each other\'s toes.\\n\\n- Suboptimal performance: A large app might load unnecessary code and assets on startup, leading to slower launch times and higher memory consumption.\\n\\nThis is the \\"Monolith Monster\\" problem, and it\'s a significant bottleneck for ambitious mobile products.\\n\\n## The Solution: Modularization with React Native and Re.Pack\\n\\nThe Super App architecture breaks down the monolithic beast into a collection of smaller, independent Mini-Apps (or modules). Think of it like a flexible shopping mall: the main building (the \\"Host\\" app) provides the core infrastructure, and individual stores (the \\"Mini-Apps\\") are plugged in and updated independently.\\n\\nReact Native, with its promise of cross-platform development, is an excellent foundation for this. But the real game-changer here is Re.Packâa powerful tool that replaces React Native\'s default bundler (Metro) with Rspack or Webpack, enabling Module Federation.\\n\\n## How it Works: The Host and the Remotes\\n\\n### The Host (Shell) App\\n\\nThis is the lean, core application you submit to the App Store/Play Store.\\n\\nIt contains essential services like navigation, authentication, and the crucial Re.Pack ScriptManager.\\n\\nIts primary job is to provide the common infrastructure and then dynamically load other modules.\\n\\nIt remains small, ensuring a quick initial download.\\n\\n### The Mini-Apps (Remotes/Modules)\\n\\nThese are separate React Native projects, each representing a distinct feature (e.g., a \\"Product Catalog,\\" \\"User Profile,\\" \\"Checkout,\\" or \\"Chat\\" module).\\n\\nEach Mini-App is bundled separately and hosted on a CDN (Content Delivery Network) or your own server.\\n\\nThey are downloaded by the Host app only when a user needs them, similar to how web pages load content on demand.\\n\\n## The Magic of Over-the-Air (OTA) Updates\\n\\nThis is where the Super App truly shines. Because Mini-Apps are just JavaScript bundles hosted externally, you gain an incredible superpower: instant, Over-the-Air (OTA) updates.\\n\\nScenario: You discover a critical bug in your \\"Checkout\\" Mini-App.\\n\\nTraditional method: Fix the bug, rebuild the entire app, submit to Apple/Google, wait for review (days), and then hope users update their app.\\n\\nRe.Pack method: Fix the bug in the \\"Checkout\\" Mini-App, rebuild only that module, upload the new bundle to your CDN. The next time a user opens the app and navigates to the checkout, the ScriptManager fetches the updated module, and the fix is liveâimmediately, without any App Store intervention.\\n\\nThis dramatically accelerates your iteration speed, allowing you to react to user feedback, deploy A/B tests, and push hotfixes with unprecedented agility.\\n\\n## Key Benefits of the Re.Pack Super App Architecture\\n\\n- Smaller initial download size: Delight users with a lightning-fast download and install.\\n\\n- Rapid iteration and OTA updates: Deploy bug fixes and new features in minutes, not days or weeks.\\n\\n- Enhanced performance: Only load the code needed for the current screen, reducing memory footprint and improving startup times.\\n\\n- Scalable team collaboration: Different teams can own and develop separate Mini-Apps independently, reducing dependency conflicts and accelerating development.\\n\\n- Improved code organization: Enforce cleaner module boundaries and encourage reusable components.\\n\\n- Future-proofing: Easily introduce or deprecate features by simply managing their availability on your CDN.\\n\\nHere\'s an illustration of how the modules load:\\n\\n\\n\\n## Under the Hood: The Re.Pack ScriptManager\\n\\nThe ScriptManager is the brain of your Super App. It\'s a client-side component within your Host app responsible for:\\n\\n- Resolving script IDs: When your app tries to render a component from a remote module, the ScriptManager intercepts the request.\\n\\n- Fetching bundles: Based on the script ID, it constructs the URL to the Mini-App\'s bundle on your CDN.\\n\\n- Caching: It intelligently caches downloaded bundles locally, so users only download them once (per version) and can use modules offline.\\n\\n- Execution: It loads and executes the JavaScript bundle into the running React Native environment.\\n\\n```js\\n// Example in your Host App\'s index.js or a dedicated setup file\\nimport { ScriptManager, Script } from \'@callstack/repack/client\'\\n\\n// Configure the ScriptManager to know where to find your modules\\nScriptManager.shared.addResolver(async (scriptId) => {\\n // In a real app, you\'d have more sophisticated versioning and environment handling\\n const getModuleUrl = (id) => {\\n // Example: For production, fetch from CDN\\n if (process.env.NODE_ENV === \'production\') {\\n return `https://your-production-cdn.com/modules/${id}.bundle`\\n }\\n // Example: For development, fetch from local dev server\\n return `http://localhost:8081/${id}.bundle` // Or your dev IP\\n }\\n\\n return {\\n url: Script.getRemoteURL(getModuleUrl(scriptId)),\\n cache: true, // Cache the module on the device for subsequent use\\n // integrity: \'sha256-...\', // Optional: For content integrity verification\\n }\\n}
1)\\n\\n// Later, in your navigation or component that uses a remote module:\\nconst RemoteUserProfile = React.lazy(() => import(\'user_profile_module/Main\'))\\n\\n// ... render <RemoteUserProfile />\\n```\\n\\n## Critical Limitations and Considerations\\n\\nWhile powerful, the Super App architecture isn\'t a silver bullet. Be aware of these key limitations:\\n\\n### Native Module Dependency\\n\\n- Rule: Any native code (Java/Kotlin for Android, Objective-C/Swift for iOS) required by a Mini-App must already be present in the Host app\'s binary.\\n\\n- Impact: If a new Mini-App needs a brand new native dependency (e.g., a specific hardware API or a unique payment SDK), you will need to update the Host app in the stores. OTA updates are for JavaScript logic and assets only.\\n\\n- Mitigation: Design your Host app to include common native dependencies upfront, or abstract native interactions through a shared native bridge.\\n\\n### Shared Runtime (Singleton Issues)\\n\\n- Rule: React, React Native, and other core libraries must be treated as singletons. The Host and all Mini-Apps must use the exact same instance and version of these libraries.\\n\\n- Impact: If a Mini-App is bundled with a different version of React than the Host, it will likely crash.\\n\\n- Mitigation: Enforce strict versioning across your Host and Mini-App projects, ideally by sharing a package.json for core dependencies or using automated checks. Re.Pack\'s Module Federation shared configuration helps manage this.\\n\\n### Complexity and Tooling\\n\\nSetting up Module Federation with Rspack/Webpack is more complex than a standard Metro-based React Native project. It requires a deeper understanding of bundler configurations.\\n\\nDebugging distributed modules can be challenging.\\n\\n### Deployment and CDN Management\\n\\nYou\'ll need a robust CDN strategy for hosting and versioning your Mini-App bundles.\\n\\nRollbacks need to be carefully planned.\\n\\n### Initial Load Time of First Module\\n\\nWhile the initial app download is small, the first time a user accesses a new module, there might be a slight delay as the bundle downloads.\\n\\n- Mitigation: Implement loading indicators, pre-fetch critical modules in the background, or use smart caching strategies.\\n\\n## The App Store Rules: A Crucial Warning\\n\\nThis is perhaps the most important section. Both Apple\'s App Store Review Guidelines and Google Play\'s Developer Program Policies have strict rules about dynamic code execution and app behavior.\\n\\n### What Is Generally Allowed (with Re.Pack)\\n\\n- JavaScript/logic updates: You are generally permitted to push new JavaScript code, UI changes, bug fixes, and feature enhancements via OTA updates. This is considered acceptable as long as it doesn\'t change the app\'s core purpose.\\n\\n- Asset updates: Images, fonts, and other static assets can also be updated dynamically.\\n\\n### What Is Strictly Forbidden (and Will Lead to Rejection or Ban)\\n\\n- Changing the app\'s core purpose: You cannot use dynamic modules to fundamentally alter the app\'s functionality or purpose after it has been approved. For example, submitting a \\"Weather App\\" and then dynamically loading a \\"Gambling App\\" module is a guaranteed ban. The app\'s primary function as described in its store listing must remain consistent.\\n\\n- Introducing new native code: You cannot dynamically download and execute new native libraries or binaries that were not part of the original app binary submitted to the store.\\n\\n- Obfuscated or malicious code: Any dynamically loaded code must adhere to all platform security and privacy policies.\\n\\n### Our Recommendation\\n\\nAlways clearly communicate the breadth of your app\'s features (including potential future modules) in your App Store submission. Avoid any language that suggests the app\'s functionality could change wildly. It\'s best to frame it as \\"dynamic content updates and feature enhancements.\\"\\n\\n## Conclusion: The Future Is Modular\\n\\nThe Super App architecture with React Native and Re.Pack offers a compelling vision for modern mobile development. It empowers teams to build faster, deploy quicker, and deliver more performant, engaging experiences to users. While it introduces a layer of complexity, the benefits in terms of agility, scalability, and user satisfaction are often well worth the investment.\\n\\nBy understanding the technical nuances and respecting the crucial app store guidelines, you can leverage this powerful approach to unlock the true potential of your mobile product and stay ahead in the ever-evolving app ecosystem.\\n\\n---\\n","code":"var Component=(()=>{var p=Object.create;var l=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var N=(n,a)=>()=>(a||n((a={exports:{}}
1).exports,a),a.exports),k=(n,a)=>{for(var t in a)l(n,t,{get:a[t],enumerable:!0})},s=(n,a,t,r)=>{if(a&&typeof a==\\"object\\"||typeof a==\\"function\\")for(let i of u(a))!w.call(n,i)&&i!==t&&l(n,i,{get:()=>a[i],enumerable:!(r=m(a,i))||r.enumerable});return n};var f=(n,a,t)=>(t=n!=null?p(g(n)):{},s(a||!n||!n.__esModule?l(t,\\"default\\",{value:n,enumerable:!0}):t,n)),y=n=>s(l({},\\"__esModule\\",{value:!0}),n);var c=N((A,o)=>{o.exports=_jsx_runtime});var x={};k(x,{default:()=>h,frontmatter:()=>v});var e=f(c()),v={title:\\"Building Modular Mobile Experiences with React Native and Re.Pack\\",date:\\"2026-01-23\\",lastmod:\\"2026-01-23\\",tags:[\\"Technology\\"],draft:!1,images:\\"/static/images/blog/modular-mobile-experiance.png\\",summary:\\"How React Native and Re.Pack enable modular Super App architecture with OTA updates, smaller downloads, and team-friendly scaling.\\",layout:\\"PostLayout\\",canonicalUrl:\\"\\"};function d(n){let a={a:\\"a\\",code:\\"code\\",div:\\"div\\",h2:\\"h2\\",h3:\\"h3\\",hr:\\"hr\\",li:\\"li\\",p:\\"p\\",path:\\"path\\",pre:\\"pre\\",span:\\"span\\",svg:\\"svg\\",ul:\\"ul\\",...n.components},{Image:t}=a;return t||b(\\"Image\\",!0),(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(a.p,{children:\\"In today\'s fast-paced mobile world, user expectations are higher than ever. Apps need to be fast, small, and constantly evolving. But what if your app is a sprawling monolith with dozens of features, leading to slow load times, bloated download sizes, and a glacial update cycle dictated by app store reviews?\\"}),(0,e.jsx)(a.p,{children:\\"Enter the Super App Architecture\\\\u2014a paradigm shift that\'s transforming how we build and deploy large-scale mobile applications. This post dives deep into how you can leverage React Native with Re.Pack to create a modular, dynamic, and future-proof mobile ecosystem, tackling the common pain points head-on.\\"}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"the-problem-when-your-app-becomes-a-monolith-monster\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-problem-when-your-app-becomes-a-monolith-monster\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Problem: When Your App Becomes a Monolith Monster\\"]}),(0,e.jsx)(a.p,{children:\\"Imagine your app as a single, enormous house. Every new feature adds a new room, a new floor, or even an entire wing. Over time, this monolithic structure leads to several critical issues:\\"}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Bloated initial download size: Users are hesitant to download large apps. A massive initial download leads to abandonment, especially in regions with limited data or storage.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Slow updates and iteration: Every bug fix, every minor UI tweak, and every new feature requires a full app store submission and review process. This can take days, delaying crucial updates and slowing down your development velocity.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Increased build times: As your codebase grows, so do your build times, impacting developer productivity.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Team scaling challenges: Large, interconnected codebases become difficult for multiple independent teams to manage simultaneously without stepping on each other\'s toes.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Suboptimal performance: A large app might load unnecessary code and assets on startup, leading to slower launch times and higher memory consumption.\\"})})]}),(0,e.jsx)(a.p,{children:`This is the \\"Monolith Monster\\" problem, and it\'s a significant bottleneck for ambitious mobile products.`}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"the-solution-modularization-with-react-native-and-repack\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-solution-modularization-with-react-native-and-repack\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Solution: Modularization with React Native and Re.Pack\\"]}),(0,e.jsx)(a.p,{children:\'The Super App architecture breaks down the monolithic beast into a collection of smaller, independent Mini-Apps (or modules). Think of it like a flexible shopping mall: the main building (the \\"Host\\" app) provides the core infrastru
1cture, and individual stores (the \\"Mini-Apps\\") are plugged in and updated independently.\'}),(0,e.jsx)(a.p,{children:\\"React Native, with its promise of cross-platform development, is an excellent foundation for this. But the real game-changer here is Re.Pack\\\\u2014a powerful tool that replaces React Native\'s default bundler (Metro) with Rspack or Webpack, enabling Module Federation.\\"}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"how-it-works-the-host-and-the-remotes\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#how-it-works-the-host-and-the-remotes\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"How it Works: The Host and the Remotes\\"]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"the-host-shell-app\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-host-shell-app\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Host (Shell) App\\"]}),(0,e.jsx)(a.p,{children:\\"This is the lean, core application you submit to the App Store/Play Store.\\"}),(0,e.jsx)(a.p,{children:\\"It contains essential services like navigation, authentication, and the crucial Re.Pack ScriptManager.\\"}),(0,e.jsx)(a.p,{children:\\"Its primary job is to provide the common infrastructure and then dynamically load other modules.\\"}),(0,e.jsx)(a.p,{children:\\"It remains small, ensuring a quick initial download.\\"}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"the-mini-apps-remotesmodules\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-mini-apps-remotesmodules\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Mini-Apps (Remotes/Modules)\\"]}),(0,e.jsx)(a.p,{children:\'These are separate React Native projects, each representing a distinct feature (e.g., a \\"Product Catalog,\\" \\"User Profile,\\" \\"Checkout,\\" or \\"Chat\\" module).\'}),(0,e.jsx)(a.p,{children:\\"Each Mini-App is bundled separately and hosted on a CDN (Content Delivery Network) or your own server.\\"}),(0,e.jsx)(a.p,{children:\\"They are downloaded by the Host app only when a user needs them, similar to how web pages load content on demand.\\"}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"the-magic-of-over-the-air-ota-updates\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-magic-of-over-the-air-ota-updates\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Magic of Over-the-Air (OTA) Updates\\"]}),(0,e.jsx)(a.p,{children:\\"This is where the Super App truly shines. Because Mini-Apps are just JavaScript bundles hosted externally, you gain an incredible superpower: instant, Over-the-Air (OTA) updates.\\"}),(0,e.jsx)(a.p,{children:\'Scenario: You discover a critical bug in your \\"Checkout\\" Mini-App.\'}),(0,e.jsx)(a.p,{children:\\"Traditional method: Fix the bug, rebuild the entire app, submit to Apple/Google, wait for review (d
1ays), and then hope users update their app.\\"}),(0,e.jsx)(a.p,{children:\'Re.Pack method: Fix the bug in the \\"Checkout\\" Mini-App, rebuild only that module, upload the new bundle to your CDN. The next time a user opens the app and navigates to the checkout, the ScriptManager fetches the updated module, and the fix is live\\\\u2014immediately, without any App Store intervention.\'}),(0,e.jsx)(a.p,{children:\\"This dramatically accelerates your iteration speed, allowing you to react to user feedback, deploy A/B tests, and push hotfixes with unprecedented agility.\\"}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"key-benefits-of-the-repack-super-app-architecture\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#key-benefits-of-the-repack-super-app-architecture\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Key Benefits of the Re.Pack Super App Architecture\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Smaller initial download size: Delight users with a lightning-fast download and install.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Rapid iteration and OTA updates: Deploy bug fixes and new features in minutes, not days or weeks.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Enhanced performance: Only load the code needed for the current screen, reducing memory footprint and improving startup times.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Scalable team collaboration: Different teams can own and develop separate Mini-Apps independently, reducing dependency conflicts and accelerating development.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Improved code organization: Enforce cleaner module boundaries and encourage reusable components.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Future-proofing: Easily introduce or deprecate features by simply managing their availability on your CDN.\\"})})]}),(0,e.jsx)(a.p,{children:\\"Here\'s an illustration of how the modules load:\\"}),(0,e.jsx)(a.div,{children:(0,e.jsx)(t,{alt:\\"Modular Mobile Experience\\",src:\\"/static/images/blog/modular-mobile-experiance.png\\",width:\\"1024\\",height:\\"1024\\"})}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"under-the-hood-the-repack-scriptmanager\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#under-the-hood-the-repack-scriptmanager\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Under the Hood: The Re.Pack ScriptManager\\"]}),(0,e.jsx)(a.p,{children:\\"The ScriptManager is the brain of your Super App. It\'s a client-side component within your Host app responsible for:\\"}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Resolving script IDs: When your app tries to render a component from a remote module, the ScriptManager intercepts the request.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Fetching bundles: Based on the script ID, it constructs the URL to the Mini-App\'s bundle on your CDN.\\"})}
1),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Caching: It intelligently caches downloaded bundles locally, so users only download them once (per version) and can use modules offline.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Execution: It loads and executes the JavaScript bundle into the running React Native environment.\\"})})]}),(0,e.jsx)(a.pre,{className:\\"language-js\\",children:(0,e.jsxs)(a.code,{className:\\"language-js code-highlight\\",children:[(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[(0,e.jsx)(a.span,{className:\\"token comment\\",children:\\"// Example in your Host App\'s index.js or a dedicated setup file\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[(0,e.jsx)(a.span,{className:\\"token keyword module\\",children:\\"import\\"}),\\" \\",(0,e.jsxs)(a.span,{className:\\"token imports\\",children:[(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"{\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token maybe-class-name\\",children:\\"ScriptManager\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\",\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token maybe-class-name\\",children:\\"Script\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"}\\"})]}),\\" \\",(0,e.jsx)(a.span,{className:\\"token keyword module\\",children:\\"from\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token string\\",children:\\"\'@callstack/repack/client\'\\"}),`\\n`]}),(0,e.jsx)(a.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[(0,e.jsx)(a.span,{className:\\"token comment\\",children:\\"// Configure the ScriptManager to know where to find your modules\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[(0,e.jsx)(a.span,{className:\\"token maybe-class-name\\",children:\\"ScriptManager\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\".\\"}),(0,e.jsx)(a.span,{className:\\"token property-access\\",children:\\"shared\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\".\\"}),(0,e.jsx)(a.span,{className:\\"token function property-access method\\",children:\\"addResolver\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(a.span,{className:\\"token keyword\\",children:\\"async\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(a.span,{className:\\"token parameter\\",children:\\"scriptId\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\")\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token operator arrow\\",children:\\"=>\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"{\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token comment\\",children:\\"// In a real app, you\'d have more sophisticated versioning and environment handling\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token keyword\\",children:\\"const\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token function function-variable\\",children:\\"getModuleUrl\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token operator\\",children:\\"=\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(a.span,{className:\\"token parameter\\",children:\\"id\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\")\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token operator arrow\\",children:\\"=>\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"{\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token comment\\",children:\\"// Example: For production, fetch from CDN\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token keyword control-flow\\",children:\\"if\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"process\\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\".\\"}),(0,e.jsx)(a.span,{className:\\"token property-access\\",children:\\"env\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\".\\"}),(0,e.jsx)(a.span,{className:\\"token constant\\",children:\\"NODE_ENV\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token operator\\",children:\\"===\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token string\\",children:\\"\'production\'\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\")\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"{\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token keyword control-flow\\",children:\\"return\\"}),\\" \\",(0,e.jsxs)(a.span,{className:\\"token template-string\\",children:[(0,e.jsx)(a.span,{className:\\"token string template-punctuation\\",children:\\"`\\"}),(0,e.jsx)(a.span,{className:\\"token string\\",children:\\"https://your-production-cdn.com/modules/\\"}),(0,e.jsxs)(a.span,{className:\\"token interpolation\\",children:[(0,e.jsx)(a.span,{className:\\"token punctuation interpolation-punctuation\\",children:\\"${\\"}),\\"id\\",(0,e.jsx)(a.span,{className:\\"token punctuation interpolation-punctuation\\",children:\\"}\\"})]}),(0,e.jsx)(a.span,{className:\\"token string\\",children:\\".bundle\\"}),(0,e.jsx)(a.span,{className:\\"token string template-punctuation\\",children:\\"`\\"})]}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"}\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token comment\\",children:\\"// Example: For development, fetch from local dev server\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token keyword control-flow\\",children:\\"return\\"}),\\" \\",(0,e.jsxs)(a.span,{className:\\"token template-string\\",children:[(0,e.jsx)(a.span,{className:\\"token string template-punctuation\\",children:\\"`\\"}),(0,e.jsx)(a.span,{className:\\"token string\\",children:\\"http://localhost:8081/\\"}),(0,e.jsxs)(a.span,{className:\\"token interpolation\\",children:[(0,e.jsx)(a.span,{className:\\"token punctuation interpolation-punctuation\\",children:\\"${\\"}),\\"id\\",(0,e.jsx)(a.span,{className:\\"token punctuation interpolation-punctuation\\",children:\\"}\\"})]}),(0,e.jsx)(a.span,{className:\\"token string\\",children:\\".bundle\\"}),(0,e.jsx)(a.span,{className:\\"token string template-punctuation\\",children:\\"`\\"})]}),\\" \\",(0,e.jsx)(a.span,{className:\\"token comment\\",children:\\"// Or your dev IP\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"}\\"}),`\\n`]}),(0,e.jsx)(a.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token keyword control-flow\\",children:\\"return\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"{\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token literal-property property\\",children:\\"url\\"}),(0,e.jsx)(a.span,{className:\\"token operator\\",children:\\":\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token maybe-class-name\\",children:\\"Script\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\".\\"}),(0,e.jsx)(a.span,{className:\\"token function property-access method\\",children:\\"getRemoteURL\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(a.span,{className:\\"token function\\",children:\\"getModuleUrl\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"scriptId\\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\",\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token literal-property property\\",children:\\"cache\\"}),(0,e.jsx)(a.span,{className:\\"token operator\\",children:\\":\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token boolean\\",children:\\"true\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\",\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token comment\\",children:\\"// Cache the module on the device for subsequent use\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token comment\\",children:\\"// integrity: \'sha256-...\', // Optional: For content integrity verification\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"}\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"}\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsx)(a.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[(0,e.jsx)(a.span,{className:\\"token comment\\",children:\\"// Later, in your navigation or component that uses a remote module:\\"}),`\\n`]}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[(0,e.jsx)(a.span,{className:\\"token keyword\\",children:\\"const\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token maybe-class-name\\",children:\\"RemoteUserProfile\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token operator\\",children:\\"=\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token maybe-class-name\\",children:\\"React\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\".\\"}),(0,e.jsx)(a.span,{className:\\"token function property-access method\\",children:\\"lazy\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\")\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token operator arrow\\",children:\\"=>\\"}),\\" \\",(0,e.jsx)(a.span,{className:\\"token keyword module\\",children:\\"import\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(a.span,{className:\\"token string\\",children:\\"\'user_profile_module/Main\'\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(a.span,{className:\\"token punctuation\\",children:\\")\\"}),`\\n`]}),(0,e.jsx)(a.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(a.span,{className:\\"code-line\\",children:[(0,e.jsx)(a.span,{className:\\"token comment\\",children:\\"// ... render <RemoteUserProfile />\\"}),`\\n`]})]})}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"critical-limitations-and-considerations\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#critical-limitations-and-considerations\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Critical Limitations and Considerations\\"]}),(0,e.jsx)(a.p,{children:\\"While powerful, the Super App architecture isn\'t a silver bullet. Be aware of these key limitations:\\"}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"native-module-dependency\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#native-module-dependency\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Native Module Dependency\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Rule: Any native code (Java/Kotlin for Android, Objective-C/Swift for iOS) required by a Mini-App must already be present in the Host app\'s binary.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Impact: If a new Mini-App needs a brand new native dependency (e.g., a specific hardware API or a unique payment S
1DK), you will need to update the Host app in the stores. OTA updates are for JavaScript logic and assets only.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Mitigation: Design your Host app to include common native dependencies upfront, or abstract native interactions through a shared native bridge.\\"})})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"shared-runtime-singleton-issues\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#shared-runtime-singleton-issues\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Shared Runtime (Singleton Issues)\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Rule: React, React Native, and other core libraries must be treated as singletons. The Host and all Mini-Apps must use the exact same instance and version of these libraries.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Impact: If a Mini-App is bundled with a different version of React than the Host, it will likely crash.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Mitigation: Enforce strict versioning across your Host and Mini-App projects, ideally by sharing a package.json for core dependencies or using automated checks. Re.Pack\'s Module Federation shared configuration helps manage this.\\"})})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"complexity-and-tooling\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#complexity-and-tooling\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Complexity and Tooling\\"]}),(0,e.jsx)(a.p,{children:\\"Setting up Module Federation with Rspack/Webpack is more complex than a standard Metro-based React Native project. It requires a deeper understanding of bundler configurations.\\"}),(0,e.jsx)(a.p,{children:\\"Debugging distributed modules can be challenging.\\"}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"deployment-and-cdn-management\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#deployment-and-cdn-management\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Deployment and CDN Management\\"]}),(0,e.jsx)(a.p,{children:\\"You\'ll need a robust CDN strategy for hosting and versioning your Mini-App bundles.\\"}),(0,e.jsx)(a.p,{children:\\"Rollbacks need to be carefully planned.\\"}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"initial-load-time-of-first-module\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#initial-load-time-of-first-module\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Initial Load Time of First Module\\"]}),(0,e.jsx)(a.p,{children:\\"While the initial app download is small, the first time a user accesses a new module, there might be a slight delay as the bundle downloads.\\"}),(0,e.jsx)(a.ul,{children:(0,e.jsx)(a.li,{children:\\"Mitigation: Implement loading indicators, pre-fetch critical modules in the background, or use smart caching strategies.\\"})}
1),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"the-app-store-rules-a-crucial-warning\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-app-store-rules-a-crucial-warning\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The App Store Rules: A Crucial Warning\\"]}),(0,e.jsx)(a.p,{children:\\"This is perhaps the most important section. Both Apple\'s App Store Review Guidelines and Google Play\'s Developer Program Policies have strict rules about dynamic code execution and app behavior.\\"}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"what-is-generally-allowed-with-repack\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#what-is-generally-allowed-with-repack\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Is Generally Allowed (with Re.Pack)\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"JavaScript/logic updates: You are generally permitted to push new JavaScript code, UI changes, bug fixes, and feature enhancements via OTA updates. This is considered acceptable as long as it doesn\'t change the app\'s core purpose.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Asset updates: Images, fonts, and other static assets can also be updated dynamically.\\"})})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"what-is-strictly-forbidden-and-will-lead-to-rejection-or-ban\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#what-is-strictly-forbidden-and-will-lead-to-rejection-or-ban\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Is Strictly Forbidden (and Will Lead to Rejection or Ban)\\"]}),(0,e.jsxs)(a.ul,{children:[(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:`Changing the app\'s core purpose: You cannot use dynamic modules to fundamentally alter the app\'s functionality or purpose after it has been approved. For example, submitting a \\"Weather App\\" and then dynamically loading a \\"Gambling App\\" module is a guaranteed ban. The app\'s primary function as described in its store listing must remain consistent.`})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Introducing new native code: You cannot dynamically download and execute new native libraries or binaries that were not part of the original app b
1inary submitted to the store.\\"})}),(0,e.jsx)(a.li,{children:(0,e.jsx)(a.p,{children:\\"Obfuscated or malicious code: Any dynamically loaded code must adhere to all platform security and privacy policies.\\"})})]}),(0,e.jsxs)(a.h3,{className:\\"content-header\\",id:\\"our-recommendation\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#our-recommendation\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Our Recommendation\\"]}),(0,e.jsx)(a.p,{children:`Always clearly communicate the breadth of your app\'s features (including potential future modules) in your App Store submission. Avoid any language that suggests the app\'s functionality could change wildly. It\'s best to frame it as \\"dynamic content updates and feature enhancements.\\"`}),(0,e.jsxs)(a.h2,{className:\\"content-header\\",id:\\"conclusion-the-future-is-modular\\",children:[(0,e.jsx)(a.a,{\\"aria-hidden\\":\\"true\\",href:\\"#conclusion-the-future-is-modular\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(a.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(a.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(a.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(a.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Conclusion: The Future Is Modular\\"]}),(0,e.jsx)(a.p,{children:\\"The Super App architecture with React Native and Re.Pack offers a compelling vision for modern mobile development. It empowers teams to build faster, deploy quicker, and deliver more performant, engaging experiences to users. While it introduces a layer of complexity, the benefits in terms of agility, scalability, and user satisfaction are often well worth the investment.\\"}),(0,e.jsx)(a.p,{children:\\"By understanding the technical nuances and respecting the crucial app store guidelines, you can leverage this powerful approach to unlock the true potential of your mobile product and stay ahead in the ever-evolving app ecosystem.\\"}),(0,e.jsx)(a.hr,{})]})}function h(n={}){let{wrapper:a}=n.components||{};return a?(0,e.jsx)(a,{...n,children:(0,e.jsx)(d,{...n})}):d(n)}function b(n,a){throw new Error(\\"Expected \\"+(a?\\"component\\":\\"object\\")+\\" `\\"+n+\\"` to be defined: you likely forgot to import, pass, or provide it.\\")}return y(x);})();\\n;return Component;"},"_id":"blog/technology/modular-mobile-experiance.mdx","_raw":{"sourceFilePath":"blog/technology/modular-mobile-experiance.mdx","sourceFileName":"modular-mobile-experiance.mdx","sourceFileDir":"blog/technology","contentType":"mdx","flattenedPath":"blog/technology/modular-mobile-experiance"},"type":"Blog","readingTime":{"text":"9 min read","minutes":8.225,"time":493500,"words":1645},"slug":"technology/modular-mobile-experiance","path":"blog/technology/modular-mobile-experiance","filePath":"blog/technology/modular-mobile-experiance.mdx","toc":[{"value":"The Problem: When Your App Becomes a Monolith Monster","url":"#the-problem-when-your-app-becomes-a-monolith-monster","depth":2},{"value":"The Solution: Modularization with React Native and Re.Pack","url":"#the-solution-modularization-with-react-native-and-repack","depth":2},{"value":"How it Works: The Host and the Remotes","url":"#how-it-works-the-host-and-the-remotes","depth":2},{"value":"The Host (Shell) App","url":"#the-host-shell-app","depth":3},{"value":"The Mini-Apps (Remotes/Modules)","url":"#the-mini-apps-remotesmodules","depth":3},{"value":"The Magic of Over-the-Air (OTA) Updates","url":"#the-magic-of-over-the-air-ota-updates","depth":2}
1,{"value":"Key Benefits of the Re.Pack Super App Architecture","url":"#key-benefits-of-the-repack-super-app-architecture","depth":2},{"value":"Under the Hood: The Re.Pack ScriptManager","url":"#under-the-hood-the-repack-scriptmanager","depth":2},{"value":"Critical Limitations and Considerations","url":"#critical-limitations-and-considerations","depth":2},{"value":"Native Module Dependency","url":"#native-module-dependency","depth":3},{"value":"Shared Runtime (Singleton Issues)","url":"#shared-runtime-singleton-issues","depth":3},{"value":"Complexity and Tooling","url":"#complexity-and-tooling","depth":3},{"value":"Deployment and CDN Management","url":"#deployment-and-cdn-management","depth":3},{"value":"Initial Load Time of First Module","url":"#initial-load-time-of-first-module","depth":3},{"value":"The App Store Rules: A Crucial Warning","url":"#the-app-store-rules-a-crucial-warning","depth":2},{"value":"What Is Generally Allowed (with Re.Pack)","url":"#what-is-generally-allowed-with-repack","depth":3},{"value":"What Is Strictly Forbidden (and Will Lead to Rejection or Ban)","url":"#what-is-strictly-forbidden-and-will-lead-to-rejection-or-ban","depth":3},{"value":"Our Recommendation","url":"#our-recommendation","depth":3},{"value":"Conclusion: The Future Is Modular","url":"#conclusion-the-future-is-modular","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"Building Modular Mobile Experiences with React Native and Re.Pack","datePublished":"2026-01-23T00:00:00.000Z","dateModified":"2026-01-23T00:00:00.000Z","description":"How React Native and Re.Pack enable modular Super App architecture with OTA updates, smaller downloads, and team-friendly scaling.","url":"https://www.devity.in/blog/technology/modular-mobile-experiance/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/blog/modular-mobile-experiance.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"The Power of Normalization vs. Denormalization","date":"2025-06-12T00:00:00.000Z","tags":["Database","Normalization","Denormalization"],"keywords":[],"lastmod":"2025-06-12T00:00:00.000Z","draft":false,"summary":"The Power of Normalization vs. Denormalization","images":"/static/images/blog/noramalization-vs-denormalization.png","layout":"PostLayout","canonicalUrl":"","faqs":[],"body":{"raw":"\\n\\n\\n## Why Schema Design Matters\\n\\nDatabase schema design is foundational to system performance, scalability, and feature development. A well-crafted schema:\\n\\n- **Accelerates product velocity** by reducing technical debt.\\n- **Adapts to growth**, avoiding bottlenecks from 10K to 10M+ users.\\n- **Prevents painful refactors** by aligning structure with long-term goals.\\n\\n### The Core Dilemma: Normalize or Denormalize?\\n\\nTeams face a critical choice:\\n\\n1. **Normalized Schemas**\\n\\n - Prioritize data integrity and minimal redundancy.\\n - Ideal for transactional systems requiring consistency (e.g., banking).\\n - Enforce rules through normal forms (1NF, 2NF, 3NF, etc.).\\n\\n2. **Denormalized Schemas**\\n - Optimize read performance and simplify queries.\\n - Trade-off: Potential redundancy for speed at scale (e.g., analytics dashboards).\\n - Common in NoSQL or read-heavy systems.\\n\\n## Navigating the Trade-offs\\n\\n- **Normalization Strengths**:\\n\\n - Maintainable, ACID-compliant, and mutation-friendly.\\n - Weakness: Complex joins can slow queries.\\n\\n- **Denormalization Strengths**:\\n - Fast reads, simple access patterns, and horizontal scalability.\\n - Weakness: Updates require careful synchronization.\\n\\n### Key Takeaways\\n\\n- **No Silver Bullet**: Use normalization for integrity, denormalization for performance.\\n- **Hybrid Approaches**: Many systems blend both (e.g., normalized writes + read-optimized caches).\\n- **Evolution Required**: Revisit schemas as usage patterns and scale change.\\n\\n_Next steps_: Audit your current schemaâs pain pointsâslow queries, rigid migrations, or redundancyâto guide your strategy.\\n","code":"var Component=(()=>{var m=Object.create;var l=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var w=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports),y=(n,e)=>{for(var i in e)l(n,i,{get:e[i],enumerable:!0})},o=(n,e,i,t)=>{if(e&&typeof e==\\"object\\"||typeof e==\\"function\\")for(let r of p(e))!f.call(n,r)&&r!==i&&l(n,r,{get:()=>e[r],enumerable:!(t=g(e,r))||t.enumerable});return n};var v=(n,e,i)=>(i=n!=null?m(u(n)):{},o(e||!n||!n.__esModule?l(i,\\"default\\",{value:n,enumerable:!0}):i,n)),z=n=>o(l({}
1,\\"__esModule\\",{value:!0}),n);var c=w((M,s)=>{s.exports=_jsx_runtime});var b={};y(b,{default:()=>h,frontmatter:()=>N});var a=v(c()),N={title:\\"The Power of Normalization vs. Denormalization\\",date:\\"2025-06-12\\",lastmod:\\"2025-06-12\\",tags:[\\"Database\\",\\"Normalization\\",\\"Denormalization\\"],draft:!1,images:\\"/static/images/blog/noramalization-vs-denormalization.png\\",summary:\\"The Power of Normalization vs. Denormalization\\",layout:\\"PostLayout\\",canonicalUrl:\\"\\"};function d(n){let e={a:\\"a\\",div:\\"div\\",em:\\"em\\",h2:\\"h2\\",h3:\\"h3\\",li:\\"li\\",ol:\\"ol\\",p:\\"p\\",path:\\"path\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",ul:\\"ul\\",...n.components},{Image:i}=e;return i||x(\\"Image\\",!0),(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.div,{children:(0,a.jsx)(i,{alt:\\"Normalization vs Denormalization\\",src:\\"/static/images/blog/noramalization-vs-denormalization-nbg.png\\",width:\\"3085\\",height:\\"1905\\"})}),(0,a.jsxs)(e.h2,{className:\\"content-header\\",id:\\"why-schema-design-matters\\",children:[(0,a.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#why-schema-design-matters\\",tabIndex:\\"-1\\",children:(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(e.span,{className:\\"content-header-link\\",children:(0,a.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,a.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,a.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Why Schema Design Matters\\"]}),(0,a.jsx)(e.p,{children:\\"Database schema design is foundational to system performance, scalability, and feature development. A well-crafted schema:\\"}),(0,a.jsxs)(e.ul,{children:[(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.strong,{children:\\"Accelerates product velocity\\"}),\\" by reducing technical debt.\\"]}),(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.strong,{children:\\"Adapts to growth\\"}),\\", avoiding bottlenecks from 10K to 10M+ users.\\"]}),(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.strong,{children:\\"Prevents painful refactors\\"}),\\" by aligning structure with long-term goals.\\"]})]}),(0,a.jsxs)(e.h3,{className:\\"content-header\\",id:\\"the-core-dilemma-normalize-or-denormalize\\",children:[(0,a.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-core-dilemma-normalize-or-denormalize\\",tabIndex:\\"-1\\",children:(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(e.span,{className:\\"content-header-link\\",children:(0,a.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,a.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,a.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"The Core Dilemma: Normalize or Denormalize?\\"]}),(0,a.jsx)(e.p,{children:\\"Teams face a critical choice:\\"}),(0,a.jsxs)(e.ol,{children:[(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.p,{children:(0,a.jsx)(e.strong,{children:\\"Normalized Schemas\\"})}),(0,a.jsxs)(e.ul,{children:[(0,a.jsx)(e.li,{children:\\"Prioritize data integrity and minimal redundancy.\\"}),(0,a.jsx)(e.li,{children:\\"Ideal for transactional systems requiring consistency (e.g., banking).\\"}),(0,a.jsx)(e.li,{children:\\"Enforce rules through normal forms (1NF, 2NF, 3NF, etc.).\\"})]})]}),(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.p,{children:(0,a.jsx)(e.strong,{children:\\"Denormalized Schemas\\"})}),(0,a.jsxs)(e.ul,{children:[(0,a.jsx)(e.li,{children:\\"Optimize read performance and simplify queries.\\"}),(0,a.jsx)(e.li,{children:\\"Trade-off: Potential redundancy for speed at scale (e.g., analytics dashboards).\\"}),(0,a.jsx)(e.li,{children:\\"Common in NoSQL or read-heavy systems.\\"})]})]})]}),(0,a.jsxs)(e.h2,{className:\\"content-header\\",id:\\"navigating-the-trade-offs\\",children:[(0,a.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#navigating-the-trade-offs\\",tabIndex:\\"-1\\",children:(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(e.span,{className:\\"content-header-link\\",children:(0,a.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,a.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,a.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Navigating the Trade-offs\\"]}),(0,a.jsxs)(e.ul,{children:[(0,a.jsxs)(e.li,{children:[(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.strong,{children:\\"Normalization Strengths\\"}),\\":\\"]}),(0,a.jsxs)(e.ul,{children:[(0,a.jsx)(e.li,{children:\\"Maintainable, ACID-compliant, and mutation-friendly.\\"}),(0,a.jsx)(e.li,{children:\\"Weakness: Complex joins can slow queries.\\"})]})]}),(0,a.jsxs)(e.li,{children:[(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.strong,{children:\\"Denormalization Strengths\\"}),\\":\\"]}),(0,a.jsxs)(e.ul,{children:[(0,a.jsx)(e.li,{children:\\"Fast reads, simple access patterns, and horizontal scalability.\\"}),(0,a.jsx)(e.li,{children:\\"Weakness: Updates require careful synchronization.\\"})]})]})]}),(0,a.jsxs)(e.h3,{className:\\"content-header\\",id:\\"key-takeaways\\",children:[(0,a.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#key-takeaways\\",tabIndex:\\"-1\\",children:(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(e.span,{className:\\"content-header-link\\",children:(0,a.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,a.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,a.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Key Takeaways\\"]}),(0,a.jsxs)(e.ul,{children:[(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.strong,{children:\\"No Silver Bullet\\"}),\\": Use normalization for integrity, denormalization for performance.\\"]}),(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.strong,{children:\\"Hybrid Approaches\\"}),\\": Many systems blend both (e.g., normalized writes + read-optimized caches).\\"]}),(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.strong,{children:\\"Evolution Required\\"}),\\": Revisit schemas as usage patterns and scale change.\\"]})]}),(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.em,{children:\\"Next steps\\"}),\\": Audit your current schema\\\\u2019s pain points\\\\u2014slow queries, rigid migrations, or redundancy\\\\u2014to guide your strategy.\\"]})]})}function h(n={}){let{wrapper:e}=n.components||{};return e?(0,a.jsx)(e,{...n,children:(0,a.jsx)(d,{...n})}):d(n)}function x(n,e){throw new Error(\\"Expected \\"+(e?\\"component\\":\\"object\\")+\\" `\\"+n+\\"` to be defined: you likely forgot to import, pass, or provide it.\\")}return z(b);})();\\n;return Component;"},"_id":"blog/technology/noramalization-vs-denormalization.mdx","_raw":{"sourceFilePath":"blog/technology/noramalization-vs-denormalization.mdx","sourceFileName":"noramalization-vs-denormalization.mdx","sourceFileDir":"blog/technology","contentType":"mdx","flattenedPath":"blog/technology/noramalization-vs-denormalization"},"type":"Blog","readingTime":{"text":"2 min read","minutes":1.06,"time":63600,"words":212},"slug":"technology/noramalization-vs-denormalization","path":"blog/technology/noramalization-vs-denormalization","filePath":"blog/technology/noramalization-vs-denormalization.mdx","toc":[{"value":"Why Schema Design Matters","url":"#why-schema-design-matters","depth":2},{"value":"The Core Dilemma: Normalize or Denormalize?","url":"#the-core-dilemma-normalize-or-denormalize","depth":3},{"value":"Navigating the Trade-offs","url":"#navigating-the-trade-offs","depth":2},{"value":"Key Takeaways","url":"#key-takeaways","depth":3}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"The Power of Normalization vs. Denormalization","datePublished":"2025-06-12T00:00:00.000Z","dateModified":"2025-06-12T00:00:00.000Z","description":"The Power of Normalization vs. Denormalization","url":"https://www.devity.in/blog/technology/noramalization-vs-denormalization/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/blog/noramalization-vs-denormalization.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"What is Semantic Search?","date":"2025-06-08T00:00:00.000Z","tags":["Technology"],"keywords":[],"lastmod":"2025-06-08T00:00:00.000Z","draft":false,"summary":"Semantic search is a type of search that uses natural language processing (NLP) to understand the meaning of a search query and return relevant results. It is different from traditional search, which uses keywords to find results.","images":"/static/images/blog/semantic-search.png","layout":"PostLayout","canonicalUrl":"","faqs":[],"body":{"raw":"\\n\\n\\nSemantic search is a type of search that uses natural language processing (NLP) to understand the meaning of a search query and return relevant results. It is different from traditional search, which uses keywords to find results.\\n\\n## How Semantic Search Works\\n\\nSemantic search uses NLP to understand the meaning of a search query and return relevant results. It is different from traditional search, which uses keywords to find results.\\n\\n## Applications of Semantic Search\\n\\nSemantic search is used in a variety of applications, including:\\n\\n- **Search Engines**: Google, Bing, and other search engines use semantic search to understand the meaning of search queries and return relevant results.\\n- **Recommendation Systems**: Semantic search is used in recommendation systems to understand the meaning of user queries and return relevant results.\\n- **Chatbots and Virtual Assistants**: Semantic search is used in chatbots and virtual assistants to understand the meaning of user queries and return relevant results.\\n\\n## Why Semantic Search is Important\\n\\nSemantic search is important because it helps users find the information they need more easily and accurately. It is different from traditional search, which uses keywords to find results.\\n\\n## Conclusion\\n\\nSemantic search is a type of search that uses natural language processing (NLP) to understand the meaning of a search query and return relevant results. It is different from traditional search, which uses keywords to find results.\\n\\n---\\n","code":"var Component=(()=>{var u=Object.create;var s=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,p=Object.prototype.hasOwnProperty;var w=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports),y=(n,e)=>{for(var t in e)s(n,t,{get:e[t],enumerable:!0})},l=(n,e,t,i)=>{if(e&&typeof e==\\"object\\"||typeof e==\\"function\\")for(let r of g(e))!p.call(n,r)&&r!==t&&s(n,r,{get:()=>e[r],enumerable:!(i=m(e,r))||i.enumerable});return n};var v=(n,e,t)=>(t=n!=null?u(f(n)):{},l(e||!n||!n.__esModule?s(t,\\"default\\",{value:n,enumerable:!0}):t,n)),x=n=>l(s({}
1,\\"__esModule\\",{value:!0}),n);var h=w((I,c)=>{c.exports=_jsx_runtime});var N={};y(N,{default:()=>d,frontmatter:()=>S});var a=v(h()),S={title:\\"What is Semantic Search?\\",date:\\"2025-06-08\\",lastmod:\\"2025-06-08\\",tags:[\\"Technology\\"],draft:!1,images:\\"/static/images/blog/semantic-search.png\\",summary:\\"Semantic search is a type of search that uses natural language processing (NLP) to understand the meaning of a search query and return relevant results. It is different from traditional search, which uses keywords to find results.\\",layout:\\"PostLayout\\",canonicalUrl:\\"\\"};function o(n){let e={a:\\"a\\",div:\\"div\\",h2:\\"h2\\",hr:\\"hr\\",li:\\"li\\",p:\\"p\\",path:\\"path\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",ul:\\"ul\\",...n.components},{Image:t}=e;return t||k(\\"Image\\",!0),(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.div,{children:(0,a.jsx)(t,{alt:\\"Semantic Search\\",src:\\"/static/images/blog/semantic-search-nbg.png\\",width:\\"3312\\",height:\\"2268\\"})}),(0,a.jsx)(e.p,{children:\\"Semantic search is a type of search that uses natural language processing (NLP) to understand the meaning of a search query and return relevant results. It is different from traditional search, which uses keywords to find results.\\"}),(0,a.jsxs)(e.h2,{className:\\"content-header\\",id:\\"how-semantic-search-works\\",children:[(0,a.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#how-semantic-search-works\\",tabIndex:\\"-1\\",children:(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(e.span,{className:\\"content-header-link\\",children:(0,a.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,a.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,a.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"How Semantic Search Works\\"]}),(0,a.jsx)(e.p,{children:\\"Semantic search uses NLP to understand the meaning of a search query and return relevant results. It is different from traditional search, which uses keywords to find results.\\"}),(0,a.jsxs)(e.h2,{className:\\"content-header\\",id:\\"applications-of-semantic-search\\",children:[(0,a.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#applications-of-semantic-search\\",tabIndex:\\"-1\\",children:(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(e.span,{className:\\"content-header-link\\",children:(0,a.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,a.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,a.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Applications of Semantic Search\\"]}),(0,a.jsx)(e.p,{children:\\"Semantic search is used in a variety of applications, including:\\"}),(0,a.jsxs)(e.ul,{children:[(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.strong,{children:\\"Search Engines\\"}),\\": Google, Bing, and other search engines use semantic search to understand the meaning of search queries and return relevant results.\\"]}),(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.strong,{children:\\"Recommendation Systems\\"}),\\": Semantic search is used in recommendation systems to understand the meaning of user queries and return relevant results.\\"]}),(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.strong,{children:\\"Chatbots and Virtual Assistants\\"}),\\": Semantic search is used in chatbots and virtual assistants to understand the meaning of user queries and return relevant results.\\"]})]}),(0,a.jsxs)(e.h2,{className:\\"content-header\\",id:\\"why-semantic-search-is-important\\",children:[(0,a.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#why-semantic-search-is-important\\",tabIndex:\\"-1\\",children:(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(e.span,{className:\\"content-header-link\\",children:(0,a.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,a.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,a.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Why Semantic Search is Important\\"]}),(0,a.jsx)(e.p,{children:\\"Semantic search is important because it helps users find the information they need more easily and accurately. It is different from traditional search, which uses keywords to find results.\\"}),(0,a.jsxs)(e.h2,{className:\\"content-header\\",id:\\"conclusion\\",children:[(0,a.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#conclusion\\",tabIndex:\\"-1\\",children:(0,a.jsx)(a.Fragment,{children:(0,a.jsx)(e.span,{className:\\"content-header-link\\",children:(0,a.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,a.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,a.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Conclusion\\"]}),(0,a.jsx)(e.p,{children:\\"Semantic search is a type of search that uses natural language processing (NLP) to understand the meaning of a search query and return relevant results. It is different from traditional search, which uses keywords to find results.\\"}),(0,a.jsx)(e.hr,{})]})}function d(n={}){let{wrapper:e}=n.components||{};return e?(0,a.jsx)(e,{...n,children:(0,a.jsx)(o,{...n})}):o(n)}function k(n,e){throw new Error(\\"Expected \\"+(e?\\"component\\":\\"object\\")+\\" `\\"+n+\\"` to be defined: you likely forgot to import, pass, or provide it.\\")}return x(N);})();\\n;return Component;"},"_id":"blog/technology/semantic-search.mdx","_raw":{"sourceFilePath":"blog/technology/semantic-search.mdx","sourceFileName":"semantic-search.mdx","sourceFileDir":"blog/technology","contentType":"mdx","flattenedPath":"blog/technology/semantic-search"},"type":"Blog","readingTime":{"text":"2 min read","minutes":1.155,"time":69300,"words":231},"slug":"technology/semantic-search","path":"blog/technology/semantic-search","filePath":"blog/technology/semantic-search.mdx","toc":[{"value":"How Semantic Search Works","url":"#how-semantic-search-works","depth":2},{"value":"Applications of Semantic Search","url":"#applications-of-semantic-search","depth":2},{"value":"Why Semantic Search is Important","url":"#why-semantic-search-is-important","depth":2},{"value":"Conclusion","url":"#conclusion","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"What is Semantic Search?","datePublished":"2025-06-08T00:00:00.000Z","dateModified":"2025-06-08T00:00:00.000Z","description":"Semantic search is a type of search that uses natural language processing (NLP) to understand the meaning of a search query and return relevant results. It is different from traditional search, which uses keywords to find results.","url":"https://www.devity.in/blog/technology/semantic-search/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/blog/semantic-search.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"Stable Shuffled Pagination with Time-Based Seeds: Avoiding Repetition Across Pages","date":"2025-06-19T00:00:00.000Z","tags":["Technology"],"keywords":[],"lastmod":"2025-06-19T00:00:00.000Z","draft":false,"summary":"Stable Shuffled Pagination with Time-Based Seeds: Avoiding Repetition Across Pages","images":"/static/images/blog/stable-shuffled-pagination.png","layout":"PostLayout","canonicalUrl":"","faqs":[],"body":{"raw":"\\n\\n\\nIn user-facing feeds like nature content, product listings, or discovery platforms, it\'s often desirable to present items in a shuffled (random) order while still supporting pagination. However, combining **randomness**, **pagination**, and **consistency** is tricky, especially when the shuffle changes over time (e.g., daily). This article introduces the concept of **Stable Shuffled Pagination**, highlights a key edge case, and outlines how to avoid it.\\n\\n---\\n\\n## What Is Stable Shuffled Pagination?\\n\\nStable Shuffled Pagination is a technique where a list of items is presented in a randomized order that supports:\\n\\n- **Pagination**: Users can load page 1, 2, 3... etc.\\n- **Stable Order**: The random shuffle stays the same across multiple page requests.\\n- **Non-repetition**: Items seen on one page do not appear again on the next.\\n- **Periodic Change (Optional)**: The order
1changes daily, weekly, or based on a seed.\\n\\nThis is often implemented using a **deterministic random shuffle**, seeded by a value like the current date (e.g., `2025-06-19`).\\n\\n---\\n\\n## The Edge Case: Seed Flip During Pagination\\n\\n### Scenario:\\n\\n1. A user opens your app on June 19 and begins browsing nature content.\\n2. They navigate to Page 4 â the feed is seeded by `2025-06-19`, showing a consistent, randomized order.\\n3. Midnight hits; the seed changes to `2025-06-20`.\\n4. The user now loads Page 5 â it uses a new shuffle order.\\n5. As a result:\\n\\n - Items from Page 1â4 may reappear.\\n - The content flow feels broken or confusing.\\n\\nThis problem arises because the **seed used to shuffle** changed mid-session.\\n\\n---\\n\\n## Solutions to Ensure Stable Experience\\n\\n### 1. **Include the Seed in Every Request**\\n\\nLock the seed at the start of the session and pass it with every paginated request:\\n\\n```http\\nGET /feed?page=5&seed=2025-06-19\\n```\\n\\nThis ensures the same shuffle is used for all pages during the user\'s session.\\n\\n### 2. **Use Token-Based Pagination**\\n\\nEncode both the seed and the offset into a single token:\\n\\n```http\\nGET /feed?token=eyJzZWVkIjoiMjAyNS0wNi0xOSIsIm9mZnNldCI6MzB9\\n```\\n\\nThis token is stateless, yet deterministic â it locks in the session\'s random order.\\n\\n### 3. **Store Shuffle Session Server-side**\\n\\nMaintain the shuffled order or seed per session on the server. While this works, it requires session management and cleanup, making it less scalable.\\n\\n### 4. **Use Long-Lived Seeds**\\n\\nInstead of switching shuffle order daily, switch weekly or on-demand (e.g., pull to refresh). This avoids mid-session flips at midnight.\\n\\n### 5. **Generate and Persist Seed on Client Side (e.g., Flutter BLoC)**\\n\\nFor frontend-controlled sessions, generate a **random seed** on page load or refresh and store it in memory (like in a BLoC class). Use this seed for all paginated requests:\\n\\n```dart\\nclass FeedBloc extends Cubit<FeedState> {\\n final String seed = Uuid().v4();\\n\\n void fetchPage(int page) {\\n api.fetchFeed(seed: seed, page: page);\\n }\\n\\n void resetFeed() {\\n final newSeed = Uuid().v4();\\n // update state and reload page 1 with new seed\\n }\\n}\\n```\\n\\nThis approach guarantees:\\n\\n- A different shuffle for each refresh.\\n- No repeats across pages.\\n- Stateless backend requests with deterministic behavior.\\n\\n---\\n\\n## Best Practices Summary\\n\\n| Step | What to Do |\\n| --------------------- | ------------------------------------------------ |\\n| \uD83D\uDD22 Seed Shuffle | Use deterministic seed (e.g., date or UUID) |\\n| â Lock the Session | Include `seed` in all paginated requests |\\n| \uD83D\uDD10 Protect From Drift | Don\'t auto-change seed mid-session |\\n| \uD83D\uDCBE Optional: Cache | Store shuffled result or use consistent PRNG |\\n| ⨠Frontend Control | Generate & manage seed at client level if needed |\\n\\n---\\n\\n## Final Thoughts\\n\\n**Stable Shuffled Pagination** enables dynamic and engaging content presentation without compromising on UX or data consistency. But to avoid repetition and confusion, especially during time-based seed changes, itâs crucial to pass the seed consistently across pagination requests.\\n\\nBy adopting one of the recommended strategies above â including client-side seed control â you can deliver a feed that feels fresh, stable, and user-friendly.\\n\\n---\\n","code":"var Component=(()=>{var p=Object.create;var i=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var N=(a,n)=>()=>(n||a((n={exports:{}}).exports,n),n.exports),w=(a,n)=>{for(var s in n)i(a,s,{get:n[s],enumerable:!0})},r=(a,n,s,t)=>{if(n&&typeof n==\\"object\\"||typeof n==\\"function\\")for(let l of m(n))!f.call(a,l)&&l!==s&&i(a,l,{get:()=>n[l],enumerable:!(t=u(n,l))||t.enumerable});return a};var k=(a,n,s)=>(s=a!=null?p(g(a)):{},r(n||!a||!a.__esModule?i(s,\\"default\\",{value:a,enumerable:!0}):s,a)),v=a=>r(i({}
1,\\"__esModule\\",{value:!0}),a);var c=N((M,d)=>{d.exports=_jsx_runtime});var y={};w(y,{default:()=>h,frontmatter:()=>b});var e=k(c()),b={title:\\"Stable Shuffled Pagination with Time-Based Seeds: Avoiding Repetition Across Pages\\",date:\\"2025-06-19\\",lastmod:\\"2025-06-19\\",tags:[\\"Technology\\"],draft:!1,images:\\"/static/images/blog/stable-shuffled-pagination.png\\",summary:\\"Stable Shuffled Pagination with Time-Based Seeds: Avoiding Repetition Across Pages\\",layout:\\"PostLayout\\",canonicalUrl:\\"\\"};function o(a){let n={a:\\"a\\",code:\\"code\\",div:\\"div\\",h2:\\"h2\\",h3:\\"h3\\",hr:\\"hr\\",li:\\"li\\",ol:\\"ol\\",p:\\"p\\",path:\\"path\\",pre:\\"pre\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",table:\\"table\\",tbody:\\"tbody\\",td:\\"td\\",th:\\"th\\",thead:\\"thead\\",tr:\\"tr\\",ul:\\"ul\\",...a.components},{Image:s}=n;return s||x(\\"Image\\",!0),(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(n.div,{children:(0,e.jsx)(s,{alt:\\"Stable Shuffled Pagination with Time-Based Seeds: Avoiding Repetition Across Pages\\",src:\\"/static/images/blog/stable-shuffled-pagination-nbg.png\\",width:\\"3080\\",height:\\"2484\\"})}),(0,e.jsxs)(n.p,{children:[\\"In user-facing feeds like nature content, product listings, or discovery platforms, it\'s often desirable to present items in a shuffled (random) order while still supporting pagination. However, combining \\",(0,e.jsx)(n.strong,{children:\\"randomness\\"}),\\", \\",(0,e.jsx)(n.strong,{children:\\"pagination\\"}),\\", and \\",(0,e.jsx)(n.strong,{children:\\"consistency\\"}),\\" is tricky, especially when the shuffle changes over time (e.g., daily). This article introduces the concept of \\",(0,e.jsx)(n.strong,{children:\\"Stable Shuffled Pagination\\"}),\\", highlights a key edge case, and outlines how to avoid it.\\"]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"what-is-stable-shuffled-pagination\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#what-is-stable-shuffled-pagination\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"What Is Stable Shuffled Pagination?\\"]}),(0,e.jsx)(n.p,{children:\\"Stable Shuffled Pagination is a technique where a list of items is presented in a randomized order that supports:\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Pagination\\"}),\\": Users can load page 1, 2, 3... etc.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Stable Order\\"}),\\": The random shuffle stays the same across multiple page requests.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Non-repetition\\"}),\\": Items seen on one page do not appear again on the next.\\"]}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.strong,{children:\\"Periodic Change (Optional)\\"}),\\": The order changes daily, weekly, or based on a seed.\\"]})]}),(0,e.jsxs)(n.p,{children:[\\"This is often implemented using a \\",(0,e.jsx)(n.strong,{children:\\"deterministic random shuffle\\"}),\\", seeded by a value like the current date (e.g., \\",(0,e.jsx)(n.code,{children:\\"2025-06-19\\"}),\\").\\"]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"the-edge-case-seed-flip-during-pagination\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#the-edge-case-seed-flip-during-pagination\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}
1),\\"The Edge Case: Seed Flip During Pagination\\"]}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"scenario\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#scenario\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Scenario:\\"]}),(0,e.jsxs)(n.ol,{children:[(0,e.jsx)(n.li,{children:(0,e.jsx)(n.p,{children:\\"A user opens your app on June 19 and begins browsing nature content.\\"})}),(0,e.jsx)(n.li,{children:(0,e.jsxs)(n.p,{children:[\\"They navigate to Page 4 \\\\u2014 the feed is seeded by \\",(0,e.jsx)(n.code,{children:\\"2025-06-19\\"}),\\", showing a consistent, randomized order.\\"]})}),(0,e.jsx)(n.li,{children:(0,e.jsxs)(n.p,{children:[\\"Midnight hits; the seed changes to \\",(0,e.jsx)(n.code,{children:\\"2025-06-20\\"}),\\".\\"]})}),(0,e.jsx)(n.li,{children:(0,e.jsx)(n.p,{children:\\"The user now loads Page 5 \\\\u2014 it uses a new shuffle order.\\"})}),(0,e.jsxs)(n.li,{children:[(0,e.jsx)(n.p,{children:\\"As a result:\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsx)(n.li,{children:\\"Items from Page 1\\\\u20134 may reappear.\\"}),(0,e.jsx)(n.li,{children:\\"The content flow feels broken or confusing.\\"})]})]})]}),(0,e.jsxs)(n.p,{children:[\\"This problem arises because the \\",(0,e.jsx)(n.strong,{children:\\"seed used to shuffle\\"}),\\" changed mid-session.\\"]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"solutions-to-ensure-stable-experience\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#solutions-to-ensure-stable-experience\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Solutions to Ensure Stable Experience\\"]}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"1-include-the-seed-in-every-request\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#1-include-the-seed-in-every-request\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"1. \\",(0,e.jsx)(n.strong,{children:\\"Include the Seed in Every Request\\"})]}),(0,e.jsx)(n.p,{children:\\"Lock the seed at the start of the session and pass it with every paginated request:\\"}),(0,e.jsx)(n.pre,{className:\\"language-http\\",children:(0,e.jsx)(n.code,{className:\\"language-http code-highlight\\",children:(0,e.jsx)(n.span,{className:\\"code-line\\",children:`GET /feed?page=5&seed=2025-06-19\\n`})})}),(0,e.jsx)(n.p,{children:\\"This ensures the same shuffle is used for all pages during the user\'s session.\\"}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"2-use-token-based-pagination\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#2-use-token-based-pagination\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"2. \\",(0,e.jsx)(n.strong,{children:\\"Use Token-Based Pagination\\"})]}),(0,e.jsx)(n.p,{children:\\"Encode both the seed and the offset into a single token:\\"}),(0,e.jsx)(n.pre,{className:\\"language-http\\",children:(0,e.jsx)(n.code,{className:\\"language-http code-highlight\\",children:(0,e.jsx)(n.span,{className:\\"code-line\\",children:`GET /feed?token=eyJzZWVkIjoiMjAyNS0wNi0xOSIsIm9mZnNldCI6MzB9\\n`})})}),(0,e.jsx)(n.p,{children:\\"This token is stateless, yet deterministic \\\\u2014 it locks in the session\'s random order.\\"}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"3-store-shuffle-session-server-side\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#3-store-shuffle-session-server-side\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"3. \\",(0,e.jsx)(n.strong,{children:\\"Store Shuffle Session Server-side\\"})]}),(0,e.jsx)(n.p,{children:\\"Maintain the shuffled order or seed per session on the server. While this works, it requires session management and cleanup, making it less scalable.\\"}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"4-use-long-lived-seeds\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#4-use-long-lived-seeds\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"4. \\",(0,e.jsx)(n.strong,{children:\\"Use Long-Lived Seeds\\"})]}),(0,e.jsx)(n.p,{children:\\"Instead of switching shuffle order daily, switch weekly or on-demand (e.g., pull to refresh). This avoids mid-session flips at midnight.\\"}),(0,e.jsxs)(n.h3,{className:\\"content-header\\",id:\\"5-generate-and-persist-seed-on-cl
1ient-side-eg-flutter-bloc\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#5-generate-and-persist-seed-on-client-side-eg-flutter-bloc\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"5. \\",(0,e.jsx)(n.strong,{children:\\"Generate and Persist Seed on Client Side (e.g., Flutter BLoC)\\"})]}),(0,e.jsxs)(n.p,{children:[\\"For frontend-controlled sessions, generate a \\",(0,e.jsx)(n.strong,{children:\\"random seed\\"}),\\" on page load or refresh and store it in memory (like in a BLoC class). Use this seed for all paginated requests:\\"]}),(0,e.jsx)(n.pre,{className:\\"language-dart\\",children:(0,e.jsxs)(n.code,{className:\\"code-highlight language-dart\\",children:[(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"class\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token class-name\\",children:\\"FeedBloc\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"extends\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token class-name\\",children:\\"Cubit\\"}),(0,e.jsxs)(n.span,{className:\\"token generics\\",children:[(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"<\\"}),(0,e.jsx)(n.span,{className:\\"token class-name\\",children:\\"FeedState\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\">\\"})]}),\\" \\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"{\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"final\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token class-name\\",children:\\"String\\"}),\\" seed \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token class-name\\",children:\\"Uuid\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),(0,e.jsx)(n.span,{className:\\"token function\\",children:\\"v4\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\";\\"}),`\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"void\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token function\\",children:\\"fetchPage\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"int page\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"{\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" api\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),(0,e.jsx)(n.span,{className:\\"token function\\",children:\\"fetchFeed\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),\\"seed\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\":\\"}),\\" seed\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\",\\"}),\\" page\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\":\\"}),\\" page\\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\";\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"}\\"}),`\\n`]}),(0,e.jsx)(n.span,{className:\\"code-line\\",children:`\\n`}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"void\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token function\\",children:\\"resetFeed\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"{\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token keyword\\",children:\\"final\\"}),\\" newSeed \\",(0,e.jsx)(n.span,{className:\\"token operator\\",children:\\"=\\"}),\\" \\",(0,e.jsx)(n.span,{className:\\"token class-name\\",children:\\"Uuid\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\".\\"}),(0,e.jsx)(n.span,{className:\\"token function\\",children:\\"v4\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"(\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\")\\"}),(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\";\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token comment\\",children:\\"// update state and reload page 1 with new seed\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[\\" \\",(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"}\\"}),`\\n`]}),(0,e.jsxs)(n.span,{className:\\"code-line\\",children:[(0,e.jsx)(n.span,{className:\\"token punctuation\\",children:\\"}\\"}),`\\n`]})]})}),(0,e.jsx)(n.p,{children:\\"This approach guarantees:\\"}),(0,e.jsxs)(n.ul,{children:[(0,e.jsx)(n.li,{children:\\"A different shuffle for each refresh.\\"}),(0,e.jsx)(n.li,{children:\\"No repeats across pages.\\"}),(0,e.jsx)(n.li,{children:\\"Stateless backend requests with deterministic behavior.\\"})]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"best-practices-summary\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#best-practices-summary\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Best Practices Summary\\"]}),(0,e.jsxs)(n.table,{children:[(0,e.jsx)(n.thead,{children:(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.th,{children:\\"Step\\"}),(0,e.jsx)(n.th,{children:\\"What to Do\\"})]})}),(0,e.jsxs)(n.tbody,{children:[(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:\\"\\\\u{1F522} Seed Shuffle\\"}),(0,e.jsx)(n.td,{children:\\"Use deterministic seed (e.g., date or UUID)\\"})]}),(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:\\"\\\\u26D3 Lock the Session\\"}),(0,e.jsxs)(n.td,{children:[\\"Include \\",(0,e.jsx)(n.code,{children:\\"seed\\"}),\\" in all paginated requests\\"]})]}),(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:\\"\\\\u{1F510} Protect From Drift\\"}),(0,e.jsx)(n.td,{children:\\"Don\'t auto-change seed mid-session\\"})]}),(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:\\"\\\\u{1F4BE} Optional: Cache\\"}),(0,e.jsx)(n.td,{children:\\"Store shuffled result or use consistent PRNG\\"})]}),(0,e.jsxs)(n.tr,{children:[(0,e.jsx)(n.td,{children:\\"\\\\u2728 Frontend Control\\"}),(0,e.jsx)(n.td,{children:\\"Generate & manage seed at client level if needed\\"})]})]})]}),(0,e.jsx)(n.hr,{}),(0,e.jsxs)(n.h2,{className:\\"content-header\\",id:\\"final-thoughts\\",children:[(0,e.jsx)(n.a,{\\"aria-hidden\\":\\"true\\",href:\\"#final-thoughts\\",tabIndex:\\"-1\\",children:(0,e.jsx)(e.Fragment,{children:(0,e.jsx)(n.span,{className:\\"content-header-link\\",children:(0,e.jsxs)(n.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,e.jsx)(n.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,e.jsx)(n.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Final Thoughts\\"]}),(0,e.jsxs)(n.p,{children:[(0,e.jsx)(n.strong,{children:\\"Stable Shuffled Pagination\\"}),\\" enables dynamic and engaging content presentation without compromising on UX or data consistency. But to avoid repetition and confusion, especially during time-based seed changes, it\\\\u2019s crucial to pass the seed consistently across pagination requests.\\"]}),(0,e.jsx)(n.p,{children:\\"By adopting one of the recommended strategies above \\\\u2014 including client-side seed control \\\\u2014 you can deliver a feed that feels fresh, stable, and user-friendly.\\"}),(0,e.jsx)(n.hr,{})]})}function h(a={}){let{wrapper:n}=a.components||{};return n?(0,e.jsx)(n,{...a,children:(0,e.jsx)(o,{...a})}):o(a)}function x(a,n){throw new Error(\\"Expected \\"+(n?\\"component\\":\\"object\\")+\\" `\\"+a+\\"` to be defined: you likely forgot to import, pass, or provide it.\\")}return v(y);})();\\n;return Component;"},"_id":"blog/technology/stable-shuffled-pagination.mdx","_raw":{"sourceFilePath":"blog/technology/stable-shuffled-pagination.mdx","sourceFileName":"stable-shuffled-pagination.mdx","sourceFileDir":"blog/technology","contentType":"mdx","flattenedPath":"blog/technology/stable-shuffled-pagination"},"type":"Blog","readingTime":{"text":"4 min read","minutes":3.27,"time":196200,"words":654},"slug":"technology/stable-shuffled-pagination","path":"blog/technology/stable-shuffled-pagination","filePath":"blog/technology/stable-shuffled-pagination.mdx","toc":[{"value":"What Is Stable Shuffled Pagination?","url":"#what-is-stable-shuffled-pagination","depth":2}
1,{"value":"The Edge Case: Seed Flip During Pagination","url":"#the-edge-case-seed-flip-during-pagination","depth":2},{"value":"Scenario:","url":"#scenario","depth":3},{"value":"Solutions to Ensure Stable Experience","url":"#solutions-to-ensure-stable-experience","depth":2},{"value":"1. Include the Seed in Every Request","url":"#1-include-the-seed-in-every-request","depth":3},{"value":"2. Use Token-Based Pagination","url":"#2-use-token-based-pagination","depth":3},{"value":"3. Store Shuffle Session Server-side","url":"#3-store-shuffle-session-server-side","depth":3},{"value":"4. Use Long-Lived Seeds","url":"#4-use-long-lived-seeds","depth":3},{"value":"5. Generate and Persist Seed on Client Side (e.g., Flutter BLoC)","url":"#5-generate-and-persist-seed-on-client-side-eg-flutter-bloc","depth":3},{"value":"Best Practices Summary","url":"#best-practices-summary","depth":2},{"value":"Final Thoughts","url":"#final-thoughts","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"Stable Shuffled Pagination with Time-Based Seeds: Avoiding Repetition Across Pages","datePublished":"2025-06-19T00:00:00.000Z","dateModified":"2025-06-19T00:00:00.000Z","description":"Stable Shuffled Pagination with Time-Based Seeds: Avoiding Repetition Across Pages","url":"https://www.devity.in/blog/technology/stable-shuffled-pagination/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/blog/stable-shuffled-pagination.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}},{"title":"What is Idempotency?","date":"2024-01-04T00:00:00.000Z","tags":["Technology"],"keywords":[],"lastmod":"2024-01-04T00:00:00.000Z","draft":false,"summary":"Idempotency refers to a property of certain operations, especially in computing and mathematics, where performing the operation multiple times produces the same result as performing it just once. In other words, an idempotent operation can be executed multiple times without changing the outcome after the first application.","images":"/static/images/blog/idempotency-cover.png","layout":"PostLayout","canonicalUrl":"https://blog.devity.in/technology/what-is-idempotency/","faqs":[],"body":{"raw":"\\n\\n\\n# Understanding Idempotency\\n\\nIdempotency refers to a property of certain operations, especially in computing and mathematics, where performing the operation multiple times produces the same result as performing it just once. In other words, an idempotent operation can be executed multiple times without changing the outcome after the first application.\\n\\n## Examples\\n\\n### HTTP Methods\\n\\nIn web development, certain HTTP methods are designed to be idempotent. For instance:\\n\\n- **GET**: Requesting a resource (e.g., a webpage) multiple times will return the same resource without modifying it.\\n- **PUT**: Updating a resource with the same data multiple times has the same effect as updating it once.\\n- **DELETE**: Deleting a resource, even if attempted multiple times, will result in the resource being deleted (or stay deleted after the first attempt).\\n\\n### Mathematics\\n\\nIn mathematics, an operation is idempotent if applying it more than once gives the same result. For example, for a function `f(x)`, if `f(f(x)) = f(x)`, the function is considered idempotent.\\n\\n- The Boolean operation AND is idempotent: `true â§ true = true`\\n\\n### Databases\\n\\nIdempotency is useful in database transactions where the same transaction could be submitted multiple times. The database ensures that the end result remains consistent regardless of how many times the transaction is processed.\\n\\n## Why Idempotency is Important\\n\\nIdempotency is critical in systems like web servers or payment systems where operations might be repeated due to network failures, retries, or user errors. Ensuring an operation is idempotent helps maintain system reliability by avoiding unintended side effects of repeated requests or commands.\\n","code":"var Component=(()=>{var m=Object.create;var r=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var g=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var f=(a,e)=>()=>(e||a((e={exports:{}}).exports,e),e.exports),y=(a,e)=>{for(var n in e)r(a,n,{get:e[n],enumerable:!0})},s=(a,e,n,l)=>{if(e&&typeof e==\\"object\\"||typeof e==\\"function\\")for(let i of u(e))!w.call(a,i)&&i!==n&&r(a,i,{get:()=>e[i],enumerable:!(l=p(e,i))||l.enumerable});return a};var x=(a,e,n)=>(n=a!=null?m(g(a)):{},s(e||!a||!a.__esModule?r(n,\\"default\\",{value:a,enumerable:!0}):n,a)),v=a=>s(r({}
1,\\"__esModule\\",{value:!0}),a);var d=f((k,o)=>{o.exports=_jsx_runtime});var N={};y(N,{default:()=>h,frontmatter:()=>b});var t=x(d()),b={title:\\"What is Idempotency?\\",date:\\"2024-01-04\\",lastmod:\\"2024-01-04\\",tags:[\\"Technology\\"],draft:!1,images:\\"/static/images/blog/idempotency-cover.png\\",summary:\\"Idempotency refers to a property of certain operations, especially in computing and mathematics, where performing the operation multiple times produces the same result as performing it just once. In other words, an idempotent operation can be executed multiple times without changing the outcome after the first application.\\",layout:\\"PostLayout\\",canonicalUrl:\\"https://blog.devity.in/technology/what-is-idempotency/\\"};function c(a){let e={a:\\"a\\",code:\\"code\\",div:\\"div\\",h1:\\"h1\\",h2:\\"h2\\",h3:\\"h3\\",li:\\"li\\",p:\\"p\\",path:\\"path\\",span:\\"span\\",strong:\\"strong\\",svg:\\"svg\\",ul:\\"ul\\",...a.components},{Image:n}=e;return n||I(\\"Image\\",!0),(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.div,{children:(0,t.jsx)(n,{alt:\\"Idempotency\\",src:\\"/static/images/blog/idempotency.png\\",width:\\"2772\\",height:\\"1872\\"})}),(0,t.jsxs)(e.h1,{className:\\"content-header\\",id:\\"understanding-idempotency\\",children:[(0,t.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#understanding-idempotency\\",tabIndex:\\"-1\\",children:(0,t.jsx)(t.Fragment,{children:(0,t.jsx)(e.span,{className:\\"content-header-link\\",children:(0,t.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,t.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,t.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Understanding Idempotency\\"]}),(0,t.jsx)(e.p,{children:\\"Idempotency refers to a property of certain operations, especially in computing and mathematics, where performing the operation multiple times produces the same result as performing it just once. In other words, an idempotent operation can be executed multiple times without changing the outcome after the first application.\\"}),(0,t.jsxs)(e.h2,{className:\\"content-header\\",id:\\"examples\\",children:[(0,t.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#examples\\",tabIndex:\\"-1\\",children:(0,t.jsx)(t.Fragment,{children:(0,t.jsx)(e.span,{className:\\"content-header-link\\",children:(0,t.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,t.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,t.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Examples\\"]}),(0,t.jsxs)(e.h3,{className:\\"content-header\\",id:\\"http-methods\\",children:[(0,t.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#http-methods\\",tabIndex:\\"-1\\",children:(0,t.jsx)(t.Fragment,{children:(0,t.jsx)(e.span,{className:\\"content-header-link\\",children:(0,t.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,t.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,t.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"HTTP Methods\\"]}),(0,t.jsx)(e.p,{children:\\"In web development, certain HTTP methods are designed to be idempotent. For instance:\\"}),(0,t.jsxs)(e.ul,{children:[(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\\"GET\\"}),\\": Requesting a resource (e.g., a webpage) multiple times will return the same resource without modifying it.\\"]}),(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\\"PUT\\"}),\\": Updating a resource with the same data multiple times has the same effect as updating it once.\\"]}),(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.strong,{children:\\"DELETE\\"}),\\": Deleting a resource, even if attempted multiple times, will result in the resource being deleted (or stay deleted after the first attempt).\\"]})]}),(0,t.jsxs)(e.h3,{className:\\"content-header\\",id:\\"mathematics\\",children:[(0,t.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#mathematics\\",tabIndex:\\"-1\\",children:(0,t.jsx)(t.Fragment,{children:(0,t.jsx)(e.span,{className:\\"content-header-link\\",children:(0,t.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,t.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,t.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Mathematics\\"]}),(0,t.jsxs)(e.p,{children:[\\"In mathematics, an operation is idempotent if applying it more than once gives the same result. For example, for a function \\",(0,t.jsx)(e.code,{children:\\"f(x)\\"}),\\", if \\",(0,t.jsx)(e.code,{children:\\"f(f(x)) = f(x)\\"}),\\", the function is considered idempotent.\\"]}),(0,t.jsx)(e.ul,{children:(0,t.jsxs)(e.li,{children:[\\"The Boolean operation AND is idempotent: \\",(0,t.jsx)(e.code,{children:\\"true \\\\u2227 true = true\\"})]})}),(0,t.jsxs)(e.h3,{className:\\"content-header\\",id:\\"databases\\",children:[(0,t.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#databases\\",tabIndex:\\"-1\\",children:(0,t.jsx)(t.Fragment,{children:(0,t.jsx)(e.span,{className:\\"content-header-link\\",children:(0,t.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,t.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,t.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Databases\\"]}),(0,t.jsx)(e.p,{children:\\"Idempotency is useful in database transactions where the same transaction could be submitted multiple times. The database ensures that the end result remains consistent regardless of how many times the transaction is processed.\\"}),(0,t.jsxs)(e.h2,{className:\\"content-header\\",id:\\"why-idempotency-is-important\\",children:[(0,t.jsx)(e.a,{\\"aria-hidden\\":\\"true\\",href:\\"#why-idempotency-is-important\\",tabIndex:\\"-1\\",children:(0,t.jsx)(t.Fragment,{children:(0,t.jsx)(e.span,{className:\\"content-header-link\\",children:(0,t.jsxs)(e.svg,{className:\\"h-5 linkicon w-5\\",fill:\\"currentColor\\",viewBox:\\"0 0 20 20\\",xmlns:\\"http://www.w3.org/2000/svg\\",children:[(0,t.jsx)(e.path,{d:\\"M12.232 4.232a2.5 2.5 0 0 1 3.536 3.536l-1.225 1.224a.75.75 0 0 0 1.061 1.06l1.224-1.224a4 4 0 0 0-5.656-5.656l-3 3a4 4 0 0 0 .225 5.865.75.75 0 0 0 .977-1.138 2.5 2.5 0 0 1-.142-3.667l3-3Z\\"}),(0,t.jsx)(e.path,{d:\\"M11.603 7.963a.75.75 0 0 0-.977 1.138 2.5 2.5 0 0 1 .142 3.667l-3 3a2.5 2.5 0 0 1-3.536-3.536l1.225-1.224a.75.75 0 0 0-1.061-1.06l-1.224 1.224a4 4 0 1 0 5.656 5.656l3-3a4 4 0 0 0-.225-5.865Z\\"})]})})})}),\\"Why Idempotency is Important\\"]}),(0,t.jsx)(e.p,{children:\\"Idempotency is critical in systems like web servers or payment systems where operations might be repeated due to network failures, retries, or user errors. Ensuring an operation is idempotent helps maintain system reliability by avoiding unintended side effects of repeated requests or commands.\\"})]})}function h(a={}){let{wrapper:e}=a.components||{};return e?(0,t.jsx)(e,{...a,children:(0,t.jsx)(c,{...a})}):c(a)}function I(a,e){throw new Error(\\"Expected \\"+(e?\\"component\\":\\"object\\")+\\" `\\"+a+\\"` to be defined: you likely forgot to import, pass, or provide it.\\")}return v(N);})();\\n;return Component;"},"_id":"blog/technology/what-is-idempotency.mdx","_raw":{"sourceFilePath":"blog/technology/what-is-idempotency.mdx","sourceFileName":"what-is-idempotency.mdx","sourceFileDir":"blog/technology","contentType":"mdx","flattenedPath":"blog/technology/what-is-idempotency"},"type":"Blog","readingTime":{"text":"2 min read","minutes":1.29,"time":77400,"words":258},"slug":"technology/what-is-idempotency","path":"blog/technology/what-is-idempotency","filePath":"blog/technology/what-is-idempotency.mdx","toc":[{"value":"Understanding Idempotency","url":"#understanding-idempotency","depth":1},{"value":"Examples","url":"#examples","depth":2},{"value":"HTTP Methods","url":"#http-methods","depth":3},{"value":"Mathematics","url":"#mathematics","depth":3},{"value":"Databases","url":"#databases","depth":3},{"value":"Why Idempotency is Important","url":"#why-idempotency-is-important","depth":2}],"structuredData":{"@context":"https://schema.org","@type":"BlogPosting","headline":"What is Idempotency?","datePublished":"2024-01-04T00:00:00.000Z","dateModified":"2024-01-04T00:00:00.000Z","description":"Idempotency refers to a property of certain operations, especially in computing and mathematics, where performing the operation multiple times produces the same result as performing it just once. In other words, an idempotent operation can be executed multiple times without changing the outcome after the first application.","url":"https://www.devity.in/blog/technology/what-is-idempotency/","image":{"@type":"ImageObject","url":"https://www.devity.in/static/images/blog/idempotency-cover.png","width":1200,"height":630},"publisher":{"@type":"Organization","name":"Devity","logo":{"@type":"ImageObject","url":"https://www.devity.in/static/images/logo.png","width":112,"height":112}}}}]'),h=JSON.parse('[{"name":"Abhishek Thakur","avatar":"/static/images/avatar.jpg","occupation":"Software Engineer","company":"Devity","email":"[email protected]","twitter":"https://x.com/abhi_____thakur","linkedin":"https://www.linkedin.com/in/abhishekthakur0","github":"https://github.com/abhishekthakur0","body":{"raw":"","code":"var Component=(()=>{var _=Object.create;var r=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var g=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),b=(t,e)=>{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},h=(t,e,n,o)=>
1{if(e&&typeof e==\\"object\\"||typeof e==\\"function\\")for(let i of p(e))!f.call(t,i)&&i!==n&&r(t,i,{get:()=>e[i],enumerable:!(o=k(e,i))||o.enumerable});return t};var d=(t,e,n)=>(n=t!=null?_(x(t)):{},h(e||!t||!t.__esModule?r(n,\\"default\\",{value:t,enumerable:!0}):n,t)),w=t=>h(r({},\\"__esModule\\",{value:!0}),t);var c=g((y,s)=>{s.exports=_jsx_runtime});var j={};b(j,{default:()=>u,frontmatter:()=>l});var a=d(c()),l={name:\\"Abhishek Thakur\\",avatar:\\"/static/images/avatar.jpg\\",occupation:\\"Software Engineer\\",company:\\"Devity\\",email:\\"[email protected]\\",twitter:\\"https://x.com/abhi_____thakur\\",linkedin:\\"https://www.linkedin.com/in/abhishekthakur0\\",github:\\"https://github.com/abhishekthakur0\\"};function m(t){return(0,a.jsx)(a.Fragment,{})}function u(t={}){let{wrapper:e}=t.components||{};return e?(0,a.jsx)(e,{...t,children:(0,a.jsx)(m,{...t})}):m(t)}return w(j);})();\\n;return Component;"},"_id":"authors/default.mdx","_raw":{"sourceFilePath":"authors/default.mdx","sourceFileName":"default.mdx","sourceFileDir":"authors","contentType":"mdx","flattenedPath":"authors/default"},"type":"Authors","readingTime":{"text":"0 min read","minutes":0,"time":0,"words":0},"slug":"default","path":"authors/default","filePath":"authors/default.mdx","toc":[]}]');[...d,...h];var u=a(2739),p=a(7648);let m=/[\0-\x1F!-,\.\/:-@\[-\^`\{-\xA9\xAB-\xB4\xB6-\xB9\xBB-\xBF\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0378\u0379\u037E\u0380-\u0385\u0387\u038B\u038D\u03A2\u03F6\u0482\u0530\u0557\u0558\u055A-\u055F\u0589-\u0590\u05BE\u05C0\u05C3\u05C6\u05C8-\u05CF\u05EB-\u05EE\u05F3-\u060F\u061B-\u061F\u066A-\u066D\u06D4\u06DD\u06DE\u06E9\u06FD\u06FE\u0700-\u070F\u074B\u074C\u07B2-\u07BF\u07F6-\u07F9\u07FB\u07FC\u07FE\u07FF\u082E-\u083F\u085C-\u085F\u086B-\u089F\u08B5\u08C8-\u08D2\u08E2\u0964\u0965\u0970\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09F2-\u09FB\u09FD\u09FF\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A76-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF0-\u0AF8\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B70\u0B72-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BF0-\u0BFF\u0C0D\u0C11\u0C29\u0C3A-\u0C3C\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B-\u0C5F\u0C64\u0C65\u0C70-\u0C7F\u0C84\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDD\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0CFF\u0D0D\u0D11\u0D45\u0D49\u0D4F-\u0D53\u0D58-\u0D5E\u0D64\u0D65\u0D70-\u0D79\u0D80\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF4-\u0E00\u0E3B-\u0E3F\u0E4F\u0E5A-\u0E80\u0E83\u0E85\u0E8B\u0EA4\u0EA6\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F01-\u0F17\u0F1A-\u0F1F\u0F2A-\u0F34\u0F36\u0F38\u0F3A-\u0F3D\u0F48\u0F6D-\u0F70\u0F85\u0F98\u0FBD-\u0FC5\u0FC7-\u0FFF\u104A-\u104F\u109E\u109F\u10C6\u10C8-\u10CC\u10CE\u10CF\u10FB\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u1360-\u137F\u1390-\u139F\u13F6\u13F7\u13FE-\u1400\u166D\u166E\u1680\u169B-\u169F\u16EB-\u16ED\u16F9-\u16FF\u170D\u1715-\u171F\u1735-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17D4-\u17D6\u17D8-\u17DB\u17DE\u17DF\u17EA-\u180A\u180E\u180F\u181A-\u181F\u1879-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u1945\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DA-\u19FF\u1A1C-\u1A1F\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1AA6\u1AA8-\u1AAF\u1AC1-\u1AFF\u1B4C-\u1B4F\u1B5A-\u1B6A\u1B74-\u1B7F\u1BF4-\u1BFF\u1C38-\u1C3F\u1C4A-\u1C4C\u1C7E\u1C7F\u1C89-\u1C8F\u1CBB\u1CBC\u1CC0-\u1CCF\u1CD3\u1CFB-\u1CFF\u1DFA\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FBD\u1F
1BF-\u1FC1\u1FC5\u1FCD-\u1FCF\u1FD4\u1FD5\u1FDC-\u1FDF\u1FED-\u1FF1\u1FF5\u1FFD-\u203E\u2041-\u2053\u2055-\u2070\u2072-\u207E\u2080-\u208F\u209D-\u20CF\u20F1-\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F-\u215F\u2189-\u24B5\u24EA-\u2BFF\u2C2F\u2C5F\u2CE5-\u2CEA\u2CF4-\u2CFF\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D70-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E00-\u2E2E\u2E30-\u3004\u3008-\u3020\u3030\u3036\u3037\u303D-\u3040\u3097\u3098\u309B\u309C\u30A0\u30FB\u3100-\u3104\u3130\u318F-\u319F\u31C0-\u31EF\u3200-\u33FF\u4DC0-\u4DFF\u9FFD-\u9FFF\uA48D-\uA4CF\uA4FE\uA4FF\uA60D-\uA60F\uA62C-\uA63F\uA673\uA67E\uA6F2-\uA716\uA720\uA721\uA789\uA78A\uA7C0\uA7C1\uA7CB-\uA7F4\uA828-\uA82B\uA82D-\uA83F\uA874-\uA87F\uA8C6-\uA8CF\uA8DA-\uA8DF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA954-\uA95F\uA97D-\uA97F\uA9C1-\uA9CE\uA9DA-\uA9DF\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A-\uAA5F\uAA77-\uAA79\uAAC3-\uAADA\uAADE\uAADF\uAAF0\uAAF1\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB5B\uAB6A-\uAB6F\uABEB\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uE000-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB29\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBB2-\uFBD2\uFD3E-\uFD4F\uFD90\uFD91\uFDC8-\uFDEF\uFDFC-\uFDFF\uFE10-\uFE1F\uFE30-\uFE32\uFE35-\uFE4C\uFE50-\uFE6F\uFE75\uFEFD-\uFF0F\uFF1A-\uFF20\uFF3B-\uFF3E\uFF40\uFF5B-\uFF65\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDD3F\uDD75-\uDDFC\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEE1-\uDEFF\uDF20-\uDF2C\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDF9F\uDFC4-\uDFC7\uDFD0\uDFD6-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCAF\uDCD4-\uDCD7\uDCFC-\uDCFF\uDD28-\uDD2F\uDD64-\uDDFF\uDF37-\uDF3F\uDF56-\uDF5F\uDF68-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56-\uDC5F\uDC77-\uDC7F\uDC9F-\uDCDF\uDCF3\uDCF6-\uDCFF\uDD16-\uDD1F\uDD3A-\uDD7F\uDDB8-\uDDBD\uDDC0-\uDDFF\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE36\uDE37\uDE3B-\uDE3E\uDE40-\uDE5F\uDE7D-\uDE7F\uDE9D-\uDEBF\uDEC8\uDEE7-\uDEFF\uDF36-\uDF3F\uDF56-\uDF5F\uDF73-\uDF7F\uDF92-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCFF\uDD28-\uDD2F\uDD3A-\uDE7F\uDEAA\uDEAD-\uDEAF\uDEB2-\uDEFF\uDF1D-\uDF26\uDF28-\uDF2F\uDF51-\uDFAF\uDFC5-\uDFDF\uDFF7-\uDFFF]|\uD804[\uDC47-\uDC65\uDC70-\uDC7E\uDCBB-\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD40-\uDD43\uDD48-\uDD4F\uDD74\uDD75\uDD77-\uDD7F\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDFF\uDE12\uDE38-\uDE3D\uDE3F-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEA9-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC4B-\uDC4F\uDC5A-\uDC5D\uDC62-\uDC7F\uDCC6\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDC1-\uDDD7\uDDDE-\uDDFF\uDE41-\uDE43\uDE45-\uDE4F\uDE5A-\uDE7F\uDEB9-\uDEBF\uDECA-\uDEFF\uDF1B\uDF1C\uDF2C-\uDF2F\uDF3A-\uDFFF]|\uD806[\uDC3B-\uDC9F\uDCEA-\uDCFE\uDD07\uDD08\uDD0A\uDD0B\uDD14\uDD17\uDD36\uDD39\uDD3A\uDD44-\uDD4F\uDD5A-\uDD9F\uDDA8\uDDA9\uDDD8\uDDD9\uDDE2\uDDE5-\uDDFF\uDE3F-\uDE46\uDE48-\uDE4F\uDE9A-\uDE9C\uDE9E-\uDEBF\uDEF9-\uDFFF]|\uD807[\uDC09\uDC37\uDC41-\uDC4F\uDC5A-\uDC71\uDC90\uDC91\uDCA8\uDCB7-\uDCFF\uDD07\uDD0A\uDD37-\uDD39\uDD3B\uDD3E\uDD48-\uDD4F\uDD5A-\uDD5F\uDD66\uDD69\uDD8F\uDD92\uDD99-\uDD9F\uDDAA-\uDEDF\uDEF7-\uDFAF\uDFB1-\uDFFF]|\uD808[\uDF9A-\uDFFF]|\uD809[\uDC6F-\uDC7F\uDD44-\uDFFF]|[\uD80A\uD80B\uD80E-\uD810\uD812-\uD819\uD824-\uD82B\uD82D\uD82E\uD830-\uD833\uD837\uD839\uD83D\uD83F\uD87B-\uD87D\uD87F\uD885-\uDB3F\uDB41-\uDBFF][\uDC00-\uDFFF]|\uD80D[\uDC2F-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDECF\uDEEE\uDEEF\uDEF5-\uDEFF\uDF37-\uDF3F\uDF44-\uDF4F\uDF5A-\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD81B[\uDC00-\uDE3F\uDE80-\uDEFF\uDF4B-\uDF4E\uDF88-\uDF8E\uDFA0-\uDFDF\uDFE2\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD821[\uDFF8-\uDFFF]|\uD823[\uDCD6-\uDCFF\uDD09-\uDFFF]|\uD82C[\uDD1F-\uDD4F\uDD53-\uDD63\uDD68-\uDD6F\uDEFC-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A-\uDC9C\uDC9F-\uDFFF]|\uD834[\uDC00-\uDD64\uDD6A-\uDD6C\uDD73-\uDD7A\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDE41\uDE45-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3\uDFCC\uDFCD]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDCFF\uDD2D-\uDD2F\uDD3E\uDD3F\uDD4A-\uDD4D\uDD4F-\uDEBF\uDEFA-\uDFFF]|\uD83A[\uDCC5-\uDCCF\uDCD7-\uDCFF\uDD4C-\uDD4F\uDD5A-\uDFFF]|\uD83B[\uDC00-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDFFF]|\uD83C[\uDC00-\uDD2F\uDD4A-\uDD4F\uDD6A-\uDD6F\uDD8A-\uDFFF]|\uD83E[\uDC00-\uDFEF\uDFFA-\uDFFF]|\uD869[\uDEDE-\uDEFF]|\uD86D[\uDF35-\uDF3F]|\uD86E[\uDC1E\uDC1F]|\uD873[\uDEA2-\uDEAF]|\uD87A[\uDFE1-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD884[\uDF4B-\uDFFF]|\uDB40[\uDC00-\uDCFF\uDDF0-\uDFFF]/g;var g=e=>{var n;let{text:a}=e;return(0,t.jsx)(p.default,{href:"/tags/".concat("string"!=typeof(n=a)?"":(n=n.toLowerCase()).replace(m,"").replace(/ /g,"-"),"/"),className:"mr-3 text-sm font-medium uppercase text-primary-500 transition delay-150 duration-300 ease-in-out hover:-translate-y-1 hover:scale-105 hover:text-primary-400",children:a.split(" ").join("-")})},x=a(3825),j=a.n(x);function w(e){let{totalPages:n,currentPage:a}=e,s=(0,o.usePathname)().split("/")[1],r=a-1>0,i=a+1<=n;return(0,t.jsx)("div",{className:"w-full space-y-2 pb-8 pt-6 md:space-y-5",children:(0,t.jsxs)("nav",{className:"flex justify-between",children:[!r&&(0,t.jsx)("button",{className:"cursor-auto disabled:opacity-50",disabled:!r,children:"Previous"}),r&&(0,t.jsx)(u.default,{href:a-1==1?"/".concat(s,"/"):"/".concat(s,"/page/").concat(a-1),rel:"prev",children:"Previous"}),(0,t.jsxs)("span",{children:[a," of ",n]}),!i&&(0,t.jsx)("button",{className:"cursor-auto disabled:opacity-50",disabled:!i,children:"Next"}),i&&(0,t.jsx)(u.default,{href:"/".concat(s,"/page/").concat(a+1),rel:"next",children:"Next"})]})})}function y(e){let{posts:n,title:a,initialDisplayPosts:s=[],pagination:r,hidePagination:o=!1}=e,d=s.length>0?s:n;return(0,t.jsx)("div",{className:"flex flex-col gap-4",children:(0,t.jsx)("div",{className:"flex gap-4 py-12 sm:gap-6 sm:py-16 lg:py-20 xl:gap-8",children:(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"grid grid-cols-1 gap-8 sm:grid-cols-2 lg:gap-y-12 xl:grid-cols-3",children:d.map((e,n)=>{let{path:a,date:s,title:r,summary:o,tags:d,images:p}=e,{avatar:m,name:x}=c(h.find(e=>"default"===e.slug),["body","_raw","_id"]),w=n<6;return(0,t.jsxs)("article",{className:"flex flex-col gap-2 space-y-2 xl:space-y-0",children:[(0,t.jsxs)(u.default,{href:"/".concat(a),className:"flex flex-col gap-4 space-y-2 xl:space-y-0",children:[p&&(0,t.jsx)(i,{alt:r,src:p,priority:w,loading:w?void 0:"lazy",className:"h-[292px] w-[384px] rounded-lg object-cover object-center",width:384,height:292}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[m&&(0,t.jsx)(i,{src:m,alt:"avatar",width:20,height:20,className:"size-5 rounded-full"}),x," â¢",(0,t.jsx)("dd",{className:"text-base font-medium leading-6 text-stone-300",children:(0,t.jsx)("time",{dateTime:s,suppressHydrationWarning:!0,children:(0,l.p)(s,j().locale)})})]}),(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsx)("h2",{className:"text-2xl font-bold leading-8 tracking-tight text-stone-100",children:r}),(0,t.jsx)("p",{className:"prose max-w-none text-stone-300",children:o})]})]}),(0,t.jsx)("div",{className:"flex flex-wrap",children:null==d?void 0:d.map(e=>(0,t.jsx)(g,{text:e},e))})]},a)})}),!o&&(0,t.jsx)("div",{className:"flex justify-center ",children:r&&r.totalPages>1&&(0,t.jsx)(w,{currentPage:r.currentPage,totalPages:r.totalPages})})]})})})}},3145:function(e,n,a){"use strict";a.d(n,{default:function(){return s.a}});var t=a(8461),s=a.n(t)},9376:function(e,n,a){"use strict";var t=a(5475);a.o(t,"usePathname")&&a.d(n,{usePathname:function(){return t.usePathname}}),a.o(t,"useRouter")&&a.d(n,{useRouter:function(){return t.useRouter}}),a.o(t,"useSearchParams")&&a.d(n,{useSearchParams:function(){return t.useSearchParams}})},257:function(e,n,a){"use strict";var t,s;e.exports=(null==(t=a.g.process)?void 0:t.env)&&"object"==typeof(null==(s=a.g.process)?void 0:s.env)?a.g.process:a(4227)},4227:function(e){!function(){var n={229:function(e){var n,a,t,s=e.exports={};function r(){throw Error("setTimeout has not been defined")}function i(){throw Error("clearTimeout has not been defined")}function o(e){if(n===setTimeout)return setTimeout(e,0);if((n===r||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(a){try{return n.call(null,e,0)}catch(a){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:r}catch(e){n=r}try{a="function"==typeof clearTimeout?clearTimeout:i}catch(e){a=i}}();var l=[],c=!1,d=-1;function h(){c&&t&&(c=!1,t.length?l=t.concat(l):d=-1,l.length&&u())}function u(){if(!c){var e=o(h);c=!0;for(var n=l.length;n;){for(t=l,l=[];++d<n;)t&&t[d].run();d=-1,n=l.length}t=null,c=!1,function(e){if(a===clearTimeout)return clearTimeout(e);if((a===i||!a)&&clearTimeout)return a=clearTimeout,clearTimeout(e);try{a(e)}catch(n){try{return a.call(null,e)}catch(n){return a.call(this,e)}}}(e)}}function p(e,n){this.fun=e,this.array=n}function m(){}s.nextTick=function(e){var n=Array(arguments.length-1);if(arguments.length>1)for(var a=1;a<arguments.length;a++)n[a-1]=arguments[a];l.push(new p(e,n)),1!==l.length||c||o(u)},p.prototype.run=function(){this.fun.apply(null,this.array)},s.title="browser",s.browser=!0,s.env={},s.argv=[],s.version="",s.versions={},s.on=m,s.addListener=m,s.once=m,s.off=m,s.removeListener=m,s.removeAllListeners=m,s.emit=m,s.prependListener=m,s.prependOnceListener=m,s.listeners=function(e){return[]},s.binding=function(e){throw Error("process.binding is not supported")},s.cwd=function(){return"/"},s.chdir=function(e){throw Error("process.chdir is not supported")},s.umask=function(){return 0}}},a={};function t(e){var s=a[e];if(void 0!==s)return s.exports;var r=a[e]={exports:{}},i=!0;try{n[e](r,r.exports,t),i=!1}finally{i&&delete a[e]}
1return r.exports}t.ab="//";var s=t(229);e.exports=s}()},8461:function(e,n,a){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),function(e,n){for(var a in n)Object.defineProperty(e,a,{enumerable:!0,get:n[a]})}(n,{default:function(){return l},getImageProps:function(){return o}});let t=a(5287),s=a(5346),r=a(5878),i=t._(a(5084));function o(e){let{props:n}=(0,s.getImgProps)(e,{defaultLoader:i.default,imgConf:{deviceSizes:[640,750,828,1080,1200,1920,2048,3840],imageSizes:[16,32,48,64,96,128,256,384],path:"/_next/image/",loader:"default",dangerouslyAllowSVG:!1,unoptimized:!0}});for(let[e,a]of Object.entries(n))void 0===a&&delete n[e];return{props:n}}let l=r.Image},6822:function(e,n,a){"use strict";a.d(n,{Cr:function(){return p},EZ:function(){return h},S0:function(){return u},ih:function(){return d}});var t=Object.defineProperty,s=Object.defineProperties,r=Object.getOwnPropertyDescriptors,i=Object.getOwnPropertySymbols,o=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,c=(e,n,a)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:a}):e[n]=a,d=(e,n)=>{for(var a in n||(n={}))o.call(n,a)&&c(e,a,n[a]);if(i)for(var a of i(n))l.call(n,a)&&c(e,a,n[a]);return e},h=(e,n)=>s(e,r(n)),u=(e,n)=>{var a={};for(var t in e)o.call(e,t)&&0>n.indexOf(t)&&(a[t]=e[t]);if(null!=e&&i)for(var t of i(e))0>n.indexOf(t)&&l.call(e,t)&&(a[t]=e[t]);return a},p=(e,n,a)=>new Promise((t,s)=>{var r=e=>{try{o(a.next(e))}catch(e){s(e)}},i=e=>{try{o(a.throw(e))}catch(e){s(e)}},o=e=>e.done?t(e.value):Promise.resolve(e.value).then(r,i);o((a=a.apply(e,n)).next())})},1235:function(e,n,a){"use strict";a.d(n,{p:function(){return t}});var t=(e,n="en-US")=>new Date(e).toLocaleDateString(n,{year:"numeric",month:"long",day:"numeric"})}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.