(function(){const posthogKey = "phc\_oMfVwfGjzwkE5n7cCaDf25rTm7WaYn8rH4FnvsVq57Zb"; const posthogHost = "https://i.buildy.so"; const forceAnalytics = false; const analyticsHosts = \["buildy.so","www.buildy.so","usecharming.com","www.usecharming.com"\]; const charmingBuildId = "d142f067d067e64cefefc0365f26e471ef22927d"; const charmingServiceName = "www"; const analyticsIdCookie = "charming\_marketing\_identity\_seen"; const legacyAnalyticsIdCookie = "buildy\_marketing\_identity\_seen"; const analyticsIdCookieMaxAgeSeconds = 31536000; !function(t,e){var o,n,p,r;e.\_\_SV||(window.posthog && window.posthog.\_\_loaded)||(window.posthog=e,e.\_i=\[\],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t\[o\[0\]\],e=o\[1\]),t\[e\]=function(){t.push(\[e\].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api\_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")\[0\]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e\[a\]=\[\]:a="posthog",u.people=u.people||\[\],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init os ds Ie us vs ss ls capture calculateEventProperties register register\_once register\_for\_session unregister unregister\_for\_session ws getFeatureFlag getFeatureFlagPayload getFeatureFlagResult isFeatureEnabled reloadFeatureFlags updateFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSurveysLoaded onSessionId getSurveys getActiveMatchingSurveys renderSurvey displaySurvey cancelPendingSurvey canRenderSurvey canRenderSurveyAsync identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get\_distinct\_id getGroups get\_session\_id get\_session\_replay\_url alias set\_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException startExceptionAutocapture stopExceptionAutocapture loadToolbar get\_property getSessionProperty bs ps createPersonProfile setInternalOrTestUser ys es $s opt\_in\_capturing opt\_out\_capturing has\_opted\_in\_capturing has\_opted\_out\_capturing get\_explicit\_consent\_status is\_capturing clear\_opt\_in\_out\_capturing cs debug M gs getPageViewId captureTraceFeedback captureTraceMetric Qr".split(" "),n=0;n<o.length;n++)g(u,o\[n\]);e.\_i.push(\[i,s,a\])},e.\_\_SV=1)}(document,window.posthog||\[\]); var h = window.location.hostname; if (forceAnalytics || analyticsHosts.indexOf(h) !== -1) { const hashParams = new URLSearchParams(window.location.hash.substring(1)); const productDistinctId = hashParams.get('distinct\_id'); const productSessionId = hashParams.get('session\_id'); const productBootstrap = productDistinctId && productSessionId ? { distinctID: productDistinctId, sessionID: productSessionId } : null; let markerDistinctId = null; if (!productBootstrap) { const markerIdPattern = /^\[0-9a-f\]{8}-\[0-9a-f\]{4}-\[0-9a-f\]{4}-\[0-9a-f\]{4}-\[0-9a-f\]{12}$/i; var markerUsedLegacy = false; for (const markerName of \[analyticsIdCookie, legacyAnalyticsIdCookie\]) { const markerPrefix = markerName + '='; const markerCookie = document.cookie .split(';') .map(function (part) { return part.trim(); }) .find(function (part) { return part.startsWith(markerPrefix); }); if (!markerCookie) continue; try { const value = decodeURIComponent(markerCookie.slice(markerPrefix.length)); if (markerIdPattern.test(value)) { markerDistinctId = value; markerUsedLegacy = markerName === legacyAnalyticsIdCookie; break; } } catch {} } } const bootstrap = productBootstrap ?? (markerDistinctId ? { distinctID: markerDistinctId } : null); posthog.init(posthogKey, { api\_host: posthogHost, defaults: '2026-01-30', ...(bootstrap ? { bootstrap } : {}), before\_send: function (event) { if (!event) return event; const metadata = {}; if (charmingBuildId) metadata.charming\_build\_id = charmingBuildId; if (charmingServiceName) metadata.charming\_service\_name = charmingServiceName; event.properties = Object.assign({}, event.properties, metadata); return event; }, loaded: function (ph) { const distinctId = ph.get\_distinct\_id(); if (typeof distinctId !== 'string') return; if (markerUsedLegacy) { ph.capture('legacy\_state\_key\_observed', { key: legacyAnalyticsIdCookie }); } try { localStorage.setItem(analyticsIdCookie, distinctId); localStorage.removeItem(legacyAnalyticsIdCookie); } catch {} document.cookie = analyticsIdCookie + '=' + encodeURIComponent(distinctId) + '; Path=/; Max-Age=' + analyticsIdCookieMaxAgeSeconds + '; SameSite=Lax' + (window.location.protocol === 'https:' ? '; Secure' : ''); document.cookie = legacyAnalyticsIdCookie + '=; Path=/; Max-Age=0; SameSite=Lax' + (window.location.protocol === 'https:' ? '; Secure' : ''); }, }); } })();(function(){const ga4Id = "G-XG5Q0M59CD"; const forceAnalytics = false; const analyticsHosts = \["buildy.so","www.buildy.so","usecharming.com","www.usecharming.com"\]; var h = window.location.hostname; if (forceAnalytics || analyticsHosts.indexOf(h) !== -1) { window.dataLayer = window.dataLayer || \[\]; function gtag() { window.dataLayer.push(arguments); } window.gtag = gtag; gtag('consent', 'default', { ad\_storage: 'denied', ad\_user\_data: 'denied', ad\_personalization: 'denied', analytics\_storage: 'granted', }); gtag('js', new Date()); gtag('config', ga4Id); var s = document.createElement('script'); s.async = true; s.src = 'https://www.googletagmanager.com/gtag/js?id=' + ga4Id; document.head.appendChild(s); } })(); (function () { function setThemeColorMetas(theme) { var light = document.querySelector('meta\[data-theme-color="light"\]'); var dark = document.querySelector('meta\[data-theme-color="dark"\]'); if (light) light.setAttribute('media', theme === 'light' ? 'all' : 'not all'); if (dark) dark.setAttribute('media', theme === 'dark' ? 'all' : 'not all'); } try { var stored = localStorage.getItem('charming-theme'); if (stored === 'dark' || stored === 'light') { document.documentElement.setAttribute('data-theme', stored); setThemeColorMetas(stored); } } catch (\_err) { // Storage can be unavailable (private mode, disabled) — fall back to // the media query, same as a first-time visitor. } })(); How to turn a Claude artifact into a hosted app | Charming(() => { // Keep this fallback aligned with copyValueToClipboard in ./clipboard.ts. // This script runs before modules load, so it cannot import the shared helper. async function copy(value) { try { if (navigator.clipboard) { await navigator.clipboard.writeText(value); return true; } } catch { // Fall through to the textarea path for browsers that block the async API. } let fallback; try { fallback = document.createElement('textarea'); fallback.value = value; fallback.setAttribute('readonly', ''); fallback.style.position = 'fixed'; fallback.style.top = '-9999px'; document.body.appendChild(fallback); fallback.select(); return document.execCommand('copy'); } catch { return false; } finally { fallback?.remove(); } } const resetTimers = new WeakMap(); function setVisible(element, visible) { element?.classList.replace( visible ? 'opacity-0' : 'opacity-100', visible ? 'opacity-100' : 'opacity-0', ); } function resetFeedback(button, island) { const action = button.querySelector('\[data-copy-action-label\]'); const confirmed = button.querySelector('\[data-copy-confirmed-label\]'); const confirmation = island.querySelector('\[data-copy-confirmation\]'); const liveRegion = island.querySelector('\[data-copy-live-region\]'); setVisible(action, true); setVisible(confirmed, false); setVisible(confirmation, false); confirmation?.classList.replace('translate-y-0', 'translate-y-1'); if (confirmation) { confirmation.textContent = button.dataset.copySuccessMessage ?? ''; if (confirmation.dataset.copyConfirmation === 'false') { confirmation.parentElement?.classList.replace('mt-2.5', 'mt-0'); confirmation.parentElement?.classList.replace('grid-rows-\[1fr\]', 'grid-rows-\[0fr\]'); } } if (liveRegion) liveRegion.textContent = ''; resetTimers.delete(button); } function showFeedback(button, island, copied) { const action = button.querySelector('\[data-copy-action-label\]'); const confirmed = button.querySelector('\[data-copy-confirmed-label\]'); const confirmation = island.querySelector('\[data-copy-confirmation\]'); const liveRegion = island.querySelector('\[data-copy-live-region\]'); const message = copied ? (button.dataset.copySuccessMessage ?? '') : (button.dataset.copyBlockedMessage ?? ''); setVisible(action, !copied); setVisible(confirmed, copied); if (confirmation) { confirmation.textContent = message; const buttonOnlySuccess = copied && confirmation.dataset.copyConfirmation === 'false'; setVisible(confirmation, !buttonOnlySuccess); confirmation.classList.replace( buttonOnlySuccess ? 'translate-y-0' : 'translate-y-1', buttonOnlySuccess ? 'translate-y-1' : 'translate-y-0', ); if (!copied && confirmation.dataset.copyConfirmation === 'false') { confirmation.parentElement?.classList.replace('mt-0', 'mt-2.5'); confirmation.parentElement?.classList.replace('grid-rows-\[0fr\]', 'grid-rows-\[1fr\]'); } } if (liveRegion) liveRegion.textContent = message; const priorTimer = resetTimers.get(button); if (priorTimer) clearTimeout(priorTimer); resetTimers.set( button, setTimeout(() => resetFeedback(button, island), 10000), ); } document.addEventListener( 'click', async (event) => { const target = event.target instanceof Element ? event.target : null; const button = target?.closest('button\[data-copy-value\]'); const island = button?.closest('astro-island\[ssr\]'); if (!button || !island) return; showFeedback(button, island, await copy(button.dataset.copyValue ?? '')); }, true, ); })(); {"@context":"https://schema.org","@type":"BlogPosting","headline":"How to turn a Claude artifact into a hosted app","description":"Claude builds an artifact inside a chat, but it vanishes when you close the tab. Publish it through Charming and it gets its own URL and a real database.","datePublished":"2026-07-21T00:00:00.000Z","author":{"@type":"Person","name":"Akhilesh Rangani"},"publisher":{"@type":"Organization","name":"Charming","url":"https://usecharming.com/","logo":"https://usecharming.com/charming-mark.svg"},"mainEntityOfPage":"https://usecharming.com/blog/how-to-host-an-app-built-with-claude","url":"https://usecharming.com/blog/how-to-host-an-app-built-with-claude"}{"@context":"https://schema.org","@type":"HowTo","name":"How to turn a Claude artifact into a hosted app","description":"Claude builds an artifact inside a chat, but it vanishes when you close the tab. Publish it through Charming and it gets its own URL and a real database.","step":\[{"@type":"HowToStep","position":1,"name":"Build the app with Claude","text":"Tell Claude what you want and let it write the app."},{"@type":"HowToStep","position":2,"name":"Connect Charming to Claude","text":"Add https://charm.ing/mcp as a custom connector in Claude so it can publish and update hosted apps."},{"@type":"HowToStep","position":3,"name":"Publish it through Charming","text":"Ask Claude to create the app on Charming. You get back a live URL with a database behind it."},{"@type":"HowToStep","position":4,"name":"Save your data","text":"Add entries in the hosted app. The data lives on the server, not in the chat."},{"@type":"HowToStep","position":5,"name":"Reopen it later","text":"Close the conversation, open the URL later, and your data is still there."},{"@type":"HowToStep","position":6,"name":"Read or update it from another AI","text":"Point another agent at the same app over MCP or HTTP and let it read or change the same data."}\]}.blog-prose{color:var(--color-ink-light);font-size:1.125rem;line-height:1.8}.blog-prose>\*+\*{margin-top:1.5rem}.blog-prose h2,.blog-prose h3{color:var(--color-ink);font-family:var(--font-serif);letter-spacing:-.02em;font-weight:600;line-height:1.2}.blog-prose h2{margin-top:3.5rem;font-size:1.75rem}.blog-prose h3{margin-top:2.5rem;font-size:1.35rem}.blog-prose a{color:var(--color-ink);text-decoration:underline;text-decoration-color:var(--color-ink-lighter);text-underline-offset:.2em}.blog-prose ul,.blog-prose ol{padding-left:1.4rem}.blog-prose ul{list-style:outside}.blog-prose ol{list-style:decimal}.blog-prose li+li{margin-top:.5rem}.blog-prose blockquote{border-left:2px solid var(--color-rule);color:var(--color-ink-lighter);padding-left:1.25rem;font-style:italic}.blog-prose pre{border:1px solid var(--color-rule);background:var(--color-muted);padding:1rem;font-size:.85rem;line-height:1.6;overflow-x:auto}.blog-prose :not(pre)>code{background:var(--color-muted);padding:.12em .3em;font-size:.88em}.blog-prose img,.blog-prose iframe,.blog-prose video{border:1px solid var(--color-rule);border-radius:var(--radius-card);width:100%}@media (prefers-color-scheme:dark){.blog-prose img:not(.brand-comparison\_\_item img){box-sizing:border-box;filter:brightness(.92);background:#32302a;padding:.75rem}}:root\[data-theme=dark\] .blog-prose img:not(.brand-comparison\_\_item img){box-sizing:border-box;filter:brightness(.92);background:#32302a;padding:.75rem}:root\[data-theme=light\] .blog-prose img:not(.brand-comparison\_\_item img){filter:none;background:0 0;padding:0}.blog-prose figure{margin-top:2.5rem}.blog-prose .brand-comparison{border:1px solid var(--color-rule);background:var(--color-rule);grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;display:grid;overflow:hidden}.blog-prose .brand-comparison\_\_item{flex-direction:column;justify-content:center;align-items:center;gap:1.5rem;min-height:18rem;padding:2.5rem;display:flex}.blog-prose .brand-comparison\_\_item--old{background:var(--color-white);color:var(--color-ink)}.blog-prose .brand-comparison\_\_item--new{background:var(--color-card);color:var(--color-ink)}.blog-prose .brand-comparison\_\_item img{object-fit:contain;border:0;width:auto;height:10rem}.blog-prose .brand-comparison\_\_item span{font-family:Inter,system-ui,sans-serif;font-size:.8rem;font-weight:600;line-height:1}.blog-prose .brand-comparison figcaption{background:var(--color-white);grid-column:1/-1;margin:0;padding:.75rem 1rem}.blog-prose .launch-video{margin-top:0;margin-bottom:3rem}.blog-prose figcaption{color:var(--color-ink-lighter);margin-top:.75rem;font-family:Inter,system-ui,sans-serif;font-size:.8rem;line-height:1.6}@media (width<=639px){.blog-prose .brand-comparison{grid-template-columns:1fr}.blog-prose .brand-comparison\_\_item{min-height:14rem;padding:2rem}.blog-prose .brand-comparison\_\_item img{height:8rem}.blog-prose .brand-comparison figcaption{grid-column:auto}}

[![Charming](/charming-lockup.svg)![Charming](/charming-lockup-dark.svg)](/)

[Ideas](/#apps)[Pricing](/#pricing)[For Work](/work)[Blog](/blog)[Docs](/docs)

[Sign up](https://charm.ing/auth/signup)

[Ideas](/#apps)[Pricing](/#pricing)[For Work](/work)[Blog](/blog)[Docs](/docs)

(function(){try{var e=typeof window<\`u\`?window:typeof global<\`u\`?global:typeof globalThis<\`u\`?globalThis:typeof self<\`u\`?self:{};e.\_posthogReleaseId=e.\_posthogReleaseId||\`01a0751b-3b40-0000-8ea1-fdcf9b6daacb\`;var t=new e.Error().stack;t&&(e.\_posthogChunkIds=e.\_posthogChunkIds||{},e.\_posthogChunkIds\[t\]=\`05279c9f-ab8a-53ce-a85a-52d4379c83ad\`)}catch{}})();var e=document.querySelector(\`\[data-nav-menu\]\`);e&&(e.querySelectorAll(\`a\`).forEach(t=>{t.addEventListener(\`click\`,()=>{e.open=!1})}),document.addEventListener(\`pointerdown\`,t=>{e.open&&!e.contains(t.target)&&(e.open=!1)}),document.addEventListener(\`keydown\`,t=>{t.key===\`Escape\`&&e.open&&(e.open=!1,e.querySelector(\`summary\`)?.focus())})); //# chunkId=05279c9f-ab8a-53ce-a85a-52d4379c83ad

[← All stories](/blog)

# How to turn a Claude artifact into a hosted app

Claude builds an artifact inside a chat, but it vanishes when you close the tab. Publish it through Charming and it gets its own URL and a real database.

By Akhilesh Rangani·July 21, 2026

Short version: have Claude build the app, then publish it through [Charming](/). You connect Charming to Claude once, ask Claude to create the app, and you get back a hosted app with its own URL and a database behind it. Close the chat and the app is still there. Any AI you use can read or update the same data over MCP or plain HTTP.

The rest of this is the long version, with an example you can open right now: [a reading list](https://charm.ing/avi/reading-list). It tracks books through to-read, reading, and read, and it saves every change.

## Where Claude stops and Charming starts

Search around and you will see the same complaint in thread after thread: it is fun, but with “no persistent storage” an app built this way stays “just a toy.” You add real data, close the tab, and the next time you open it the thing has started over. So once the demo works, the question is always some version of the same one, the one people keep asking on Hacker News and dev.to: how do I turn this into a real app, with its own URL and a database, that does not vanish when the chat ends?

Claude is good at turning a sentence into working code while you are still chatting. What it cannot do is keep that app around after you close the tab. That gap is the reason Charming exists.

Claude writes the code, and Charming runs it. Charming gives the app a URL, stores its data, and exposes an API your agents can call, so you never stand up a server or a login system yourself. You keep the AI you already pay for. Charming is where the result lives.

## What you’ll build

A reading list. You add a book with its title and author, move it from to-read to reading to read, and give the ones you finish a star rating. Nothing private, nothing to sign in for. It remembers your books.

![A hosted reading list app showing four books grouped by status: The Pragmatic Programmer under to-read, Project Hail Mary under reading, and Dune and The Left Hand of Darkness under read with star ratings.](/blog/host-app-built-with-claude/reading-list-app.png)

The finished app, hosted on Charming with its own URL and saved data.

Open the live one here: [charm.ing/avi/reading-list](https://charm.ing/avi/reading-list).

## Step 1: Build it with Claude

Open a normal Claude chat and say what you want:

> Build me a reading list app. I want to add books with a title and author, move each one between to-read, reading, and read, and give finished books a star rating.

Claude writes it and shows you a preview. Up to here it is the same as a Claude Artifact: a live thing running inside the chat. The next steps give it a permanent URL and storage that outlives the chat.

## Step 2: Connect Charming to Claude

You do this once. Charming plugs into Claude as a custom MCP connector, which is how Claude gets to publish and update hosted apps.

1.  Copy the connector URL: `https://charm.ing/mcp`
2.  Open Claude’s connector settings at [claude.ai/customize/connectors](https://claude.ai/customize/connectors).
3.  Choose **Add custom connector**, name it Charming, paste the URL, and click **Add**.
4.  Approve it once so Claude can use Charming’s tools.

The [Claude setup page](https://charm.ing/docs/clients/claude) has the same steps with screenshots.

## Step 3: Publish it

Back in the chat, ask Claude to make it live:

> Create this on Charming so it has its own URL and saves my data.

Claude calls Charming and hands back a live link. That link is the hosted app: a public URL with a database behind it and an API other agents can hit. You did not make a repo or deploy anything.

## Step 4: Save some data

Open the URL and add a few books. Mark one as reading, finish another and give it four stars. What you type gets stored on Charming’s server, not buried in the chat transcript.

The example list has four books, one in each state, so you can see reading and read next to each other:

*   The Pragmatic Programmer, still to-read
*   Project Hail Mary, currently reading
*   Dune, read, five stars
*   The Left Hand of Darkness, read, four stars

## Step 5: Close the chat, come back later

Close the Claude conversation. Open a new tab and go straight to the app’s URL. The books are still there, same states, same ratings. The app does not need the chat that built it.

## Step 6: Use it from another AI

The app has an agent-readable API, so you are not stuck with Claude. Point another agent at the same Charming app over MCP, or hit its HTTP API, and it reads and writes the same data.

I asked Claude to add the Harry Potter series to the same list. It loaded the app to see what was already on there, then added all seven books as to-read:

![Claude using the Charming connector to open the hosted reading list app inline and add the seven Harry Potter books to it as to-read.](/blog/host-app-built-with-claude/claude-adds-books.png)

Another agent working on the same hosted app. Claude reads the list, then adds the Harry Potter series to it.

Open the app again and the new books are there. Two different chats wrote to the same app.

## About Claude Artifacts

Artifacts are a good way to get something interactive inside a chat, and a published Artifact on a paid plan can even save text and be shared by link. If that covers what you need, use it. We went through exactly what an Artifact keeps in [do Claude Artifacts save data](/do-claude-artifacts-save-data/).

Charming is a different thing. The app lives at a neutral URL that is not tied to Claude, the data is a real database instead of text capped inside one product, and any AI you use can read and change it. Claude can build it either way. Charming is for when you want the result to stand on its own.

If you are weighing this against other options in general, we wrote up [where to host an app you built with AI](/where-to-host-an-app-you-built-with-ai/).

## Frequently asked questions

**Can Claude publish an artifact as a standalone app?** A published Artifact gets a shareable link and lives inside Claude. If you want an app with its own URL and a database other agents can reach, publish it through Charming instead. Claude writes the code; Charming runs the app.

**How do I turn a Claude artifact into an app?** Connect Charming to Claude as a custom connector, then ask Claude to create the app on Charming. You get a hosted app with a database behind it that does not reset when you close the chat.

**Where should I host an app I built with Claude?** Charming is built for this. It hosts an app your AI made and handles storage, the API, and sharing for you. If you are comparing hosting options more broadly, we cover that in [where to host an app you built with AI](/where-to-host-an-app-you-built-with-ai/).

**Does the app keep working when I’m not chatting?** Yes. The app and its data live on Charming, so losing or closing the chat does not touch it. Open the URL later and everything is still there.

Related reading: [do Claude Artifacts save data](/do-claude-artifacts-save-data/), [where to host an app you built with AI](/where-to-host-an-app-you-built-with-ai/), [can you build an app inside ChatGPT](/can-you-build-an-app-inside-chatgpt/), [does ChatGPT Canvas persist](/does-chatgpt-canvas-persist/), and [personal app ideas](/personal-app-ideas/).

## The missing cloud for apps your agent builds.

Build and share your first app in a few minutes.

[Sign up](https://charm.ing/auth/signup)

[](/)

Software that’s finally yours.

[Up and running](https://status.usecharming.com "System status. Opens status.usecharming.com")

## Explore

*   [Ideas](/#apps)
*   [How it works](/how-it-works)
*   [Pricing](/#pricing)
*   [For Work](/work)
*   [Blog](/blog)

## For work

*   [Finance](/work/finance)
*   [Internal tools](/work/internal-tools)
*   [Recruiting](/work/recruiting)
*   [Consultants](/work/consultants)
*   [Marketing](/work/marketing)
*   [IT and security](/work/it)

## Works with

*   [ChatGPT](https://chatgpt.com/plugins/plugin_asdk_app_6a56c533cd7c8191b9a16cb7973a65e6)
*   [Claude](https://charm.ing/docs/clients/claude)
*   [Microsoft 365 Copilot](https://charm.ing/docs/clients/microsoft-365-copilot)
*   [Cursor](https://charm.ing/docs/clients/cursor)
*   [All setup guides](/works-with)

## Learn

*   [Docs](/docs)
*   [Guides](/guides)
*   [Contact](/contact-us)
*   [llms.txt](/llms.txt)
*   [Email us](mailto:support@usecharming.com)

Explore+

*   [Ideas](/#apps)
*   [How it works](/how-it-works)
*   [Pricing](/#pricing)
*   [For Work](/work)
*   [Blog](/blog)

For work+

*   [Finance](/work/finance)
*   [Internal tools](/work/internal-tools)
*   [Recruiting](/work/recruiting)
*   [Consultants](/work/consultants)
*   [Marketing](/work/marketing)
*   [IT and security](/work/it)

App ideas+

*   [Job application tracker](/apps/job-application-tracker)
*   [Project status](/apps/project-status-tracker)
*   [Meeting actions](/apps/meeting-action-tracker)
*   [Vendor review](/apps/vendor-review)
*   [Product launch](/apps/product-launch-tracker)
*   [Review and approval](/apps/review-approval)
*   [Quote calculator](/apps/pricing-calculator)

Works with+

*   [ChatGPT](https://chatgpt.com/plugins/plugin_asdk_app_6a56c533cd7c8191b9a16cb7973a65e6)
*   [Claude](https://charm.ing/docs/clients/claude)
*   [Microsoft 365 Copilot](https://charm.ing/docs/clients/microsoft-365-copilot)
*   [Cursor](https://charm.ing/docs/clients/cursor)
*   [All setup guides](/works-with)

Learn+

*   [Docs](/docs)
*   [Guides](/guides)
*   [Contact](/contact-us)
*   [llms.txt](/llms.txt)
*   [Email us](mailto:support@usecharming.com)

## App ideas

[Job application tracker](/apps/job-application-tracker)[Project status](/apps/project-status-tracker)[Meeting actions](/apps/meeting-action-tracker)[Vendor review](/apps/vendor-review)[Product launch](/apps/product-launch-tracker)[Review and approval](/apps/review-approval)[Quote calculator](/apps/pricing-calculator)

© 2026 Charming

[Privacy](/privacy)[Terms](/terms)[Fair use](/fair-use)[Subprocessors](/subprocessors)

charm.ing

(function(){try{var e=typeof window<\`u\`?window:typeof global<\`u\`?global:typeof globalThis<\`u\`?globalThis:typeof self<\`u\`?self:{};e.\_posthogReleaseId=e.\_posthogReleaseId||\`01a0751b-3b40-0000-8ea1-fdcf9b6daacb\`;var t=new e.Error().stack;t&&(e.\_posthogChunkIds=e.\_posthogChunkIds||{},e.\_posthogChunkIds\[t\]=\`247d408f-d424-54e5-81b1-619030ddcc48\`)}catch{}})();var e=\`charming-theme\`,t=document.documentElement,n=window.matchMedia(\`(prefers-color-scheme: dark)\`),r=()=>{let e=t.getAttribute(\`data-theme\`);return e===\`light\`||e===\`dark\`?e:n.matches?\`dark\`:\`light\`},i=document.querySelector(\`\[data-theme-toggle\]\`),a=()=>{if(!i)return;let e=r()===\`dark\`?\`light\`:\`dark\`;i.setAttribute(\`aria-label\`,\`Switch to ${e} theme\`)};a();var o=e=>{let t=document.querySelector(\`meta\[data-theme-color="light"\]\`),n=document.querySelector(\`meta\[data-theme-color="dark"\]\`);t?.setAttribute(\`media\`,e===\`light\`?\`all\`:\`not all\`),n?.setAttribute(\`media\`,e===\`dark\`?\`all\`:\`not all\`)};i?.addEventListener(\`click\`,()=>{let n=r()===\`dark\`?\`light\`:\`dark\`;t.setAttribute(\`data-theme\`,n),o(n);try{localStorage.setItem(e,n)}catch{}a()}),n.addEventListener(\`change\`,()=>{t.hasAttribute(\`data-theme\`)||a()}); //# chunkId=247d408f-d424-54e5-81b1-619030ddcc48