{entries.length === 0
- ? "Add your first key — name, value, environment. Encrypted on your device before sync."
+ ? "Add your first key — name, value, environment. Encrypted on your device in a local vault."
: "Try a different search or environment filter."}
- {/* Mobile Menu Toggle */}
-
-
- {/* Desktop Actions */}
-
- {showThemeToggle ? : null}
-
-
-
-
-
- {/* Mobile Menu */}
-
- {isMenuOpen && (
- <>
- {/* Backdrop */}
- setIsMenuOpen(false)}
- />
-
- {/* Menu Content */}
-
-
-
- >
- )}
-
-
- );
-}
\ No newline at end of file
diff --git a/apps/desktop-ui/src/components/legal-agreement-footer.tsx b/apps/desktop-ui/src/components/legal-agreement-footer.tsx
index 722f60ff..d32cd234 100644
--- a/apps/desktop-ui/src/components/legal-agreement-footer.tsx
+++ b/apps/desktop-ui/src/components/legal-agreement-footer.tsx
@@ -10,7 +10,7 @@ import {
} from "@/components/ui/dialog";
import { cn } from "@/lib/utils";
-const LAST_UPDATED = "July 14, 2026";
+const LAST_UPDATED = "July 22, 2026";
function TermsBody() {
return (
@@ -38,9 +38,9 @@ function TermsBody() {
3. Your data and encryption
The Service is local-first: the content you create with the tools is stored on your
- device. If you enable cloud sync, your data is encrypted on your device with a vault
- password that only you know, and only the encrypted result is sent to us. We never
- receive your vault password and cannot decrypt or recover your synced data.
+ device and is not sent to us. Sensitive data such as vault records is encrypted on your
+ device with a vault password that only you know. We never receive your vault password and
+ cannot decrypt or recover your vault data.
If you lose your vault password, your encrypted data cannot be recovered by anyone,
@@ -93,8 +93,8 @@ function PrivacyBody() {
MyDevTools is built to be private by design. The only personal information we hold on our
servers is your account details. Everything you create with the tools stays on
- your device unless you choose to sync it — and anything you sync is end-to-end encrypted so
- that we cannot read it.
+ your device — it is not sent to us. Sensitive vault data is additionally encrypted on your
+ device so that only you can read it.
@@ -111,17 +111,16 @@ function PrivacyBody() {
The content you create with the tools (notes, snippets, requests, keys, and other tool
data) is saved locally on your device. It is not sent to us and is not part of your
- account unless you enable cloud sync.
+ account.
-
4. Optional cloud sync (zero-knowledge)
+
4. Local encrypted vault (zero-knowledge)
- If you turn on cloud sync in Settings, your data is encrypted on your device with a vault
- password that only you know. Only the resulting encrypted blob is transmitted and stored.
- We never receive your vault password and have no way to decrypt or view your raw data —
- only you can, with your vault password.
+ Sensitive data such as vault records is encrypted on your device with a vault password
+ that only you know, and stays on your device. We never receive your vault password and
+ have no way to decrypt or view your data — only you can, with your vault password.
@@ -145,9 +144,9 @@ function PrivacyBody() {
7. Retention & deletion
- We keep account and billing data for as long as your account is active or as required by
- law. When you delete your account, we delete your account data and any encrypted synced
- blobs; data stored only on your device is removed when you delete it locally.
+ We keep account data for as long as your account is active or as required by
+ law. When you delete your account, we delete your account data; data stored on your device
+ is removed when you delete it locally.
@@ -217,7 +216,7 @@ export function LegalAgreementFooter({ className, linkClassName }: LegalAgreemen
Privacy Policy
- What we store, what stays on your device, and our zero-knowledge sync.
+ What we store, what stays on your device, and how your local vault works.
+
+`;
+}
+
+export function generateSchemaExport(format: SchemaExportFormat, fields: SchemaExportField[], collection: string): { content: string; ext: string; mime: string } {
+ switch (format) {
+ case "jsonSchema":
+ return { content: toJsonSchema(fields, collection), ext: "schema.json", mime: "application/json" };
+ case "mongoose":
+ return { content: toMongoose(fields, collection), ext: "model.js", mime: "text/javascript" };
+ case "html":
+ return { content: toHtml(fields, collection), ext: "schema.html", mime: "text/html" };
+ }
+}
diff --git a/apps/desktop-ui/src/lib/nosql-snippets.ts b/apps/desktop-ui/src/lib/nosql-snippets.ts
new file mode 100644
index 00000000..03e28b09
--- /dev/null
+++ b/apps/desktop-ui/src/lib/nosql-snippets.ts
@@ -0,0 +1,119 @@
+// MongoDB query/aggregation snippets + operator metadata for the nosql-explorer
+// Monaco completion provider. Pure data so it can be unit-tested and reused;
+// the component maps these to Monaco CompletionItems (kept out of here to avoid
+// importing monaco types into a lib module).
+//
+// `insertText` uses Monaco snippet placeholder syntax (${1:foo}) when
+// `snippet` is true. The editor language is JSON, so snippets are JSON-shaped.
+
+export interface NosqlCompletion {
+ /** Text shown in the completion list. */
+ label: string;
+ /** Short right-aligned hint (e.g. the category). */
+ detail: string;
+ /** Markdown docs shown in the details flyout. */
+ doc: string;
+ /** Text inserted on accept. */
+ insertText: string;
+ /** When true, insertText contains ${n} tab-stops (InsertAsSnippet). */
+ snippet: boolean;
+}
+
+// Query + aggregation operators. Kept flat; `detail` groups them visually.
+export const MONGO_OPERATORS: NosqlCompletion[] = [
+ // comparison
+ op("$eq", "comparison", "Matches values equal to a specified value.", `"$eq": \${1:value}`),
+ op("$ne", "comparison", "Matches values not equal to a specified value.", `"$ne": \${1:value}`),
+ op("$gt", "comparison", "Matches values greater than a specified value.", `"$gt": \${1:value}`),
+ op("$gte", "comparison", "Matches values greater than or equal to a specified value.", `"$gte": \${1:value}`),
+ op("$lt", "comparison", "Matches values less than a specified value.", `"$lt": \${1:value}`),
+ op("$lte", "comparison", "Matches values less than or equal to a specified value.", `"$lte": \${1:value}`),
+ op("$in", "comparison", "Matches any of the values in an array.", `"$in": [\${1:value}]`),
+ op("$nin", "comparison", "Matches none of the values in an array.", `"$nin": [\${1:value}]`),
+ // logical
+ op("$and", "logical", "Joins clauses with a logical AND.", `"$and": [\${1:{}}]`),
+ op("$or", "logical", "Joins clauses with a logical OR.", `"$or": [\${1:{}}]`),
+ op("$nor", "logical", "Joins clauses with a logical NOR.", `"$nor": [\${1:{}}]`),
+ op("$not", "logical", "Inverts the effect of a query expression.", `"$not": \${1:{}}`),
+ // element / evaluation
+ op("$exists", "element", "Matches documents that have the specified field.", `"$exists": \${1:true}`),
+ op("$type", "element", "Selects documents where a field is of the specified BSON type.", `"$type": "\${1:string}"`),
+ op("$regex", "evaluation", "Selects documents where values match a regular expression.", `"$regex": "\${1:pattern}", "$options": "\${2:i}"`),
+ op("$expr", "evaluation", "Allows aggregation expressions within the query language.", `"$expr": \${1:{}}`),
+ op("$mod", "evaluation", "Performs a modulo operation on a field value.", `"$mod": [\${1:divisor}, \${2:remainder}]`),
+ // array
+ op("$all", "array", "Matches arrays that contain all specified elements.", `"$all": [\${1:value}]`),
+ op("$elemMatch", "array", "Matches documents with array elements meeting all criteria.", `"$elemMatch": \${1:{}}`),
+ op("$size", "array", "Matches arrays with the specified number of elements.", `"$size": \${1:0}`),
+ // aggregation stages
+ op("$match", "stage", "Filters documents to pass only matching ones to the next stage.", `"$match": \${1:{}}`),
+ op("$project", "stage", "Reshapes documents, including/excluding fields.", `"$project": \${1:{}}`),
+ op("$group", "stage", "Groups documents by an _id expression and computes accumulators.", `"$group": { "_id": \${1:null} }`),
+ op("$sort", "stage", "Sorts documents by the specified fields.", `"$sort": { "\${1:field}": \${2:-1} }`),
+ op("$limit", "stage", "Limits the number of documents passed to the next stage.", `"$limit": \${1:10}`),
+ op("$skip", "stage", "Skips a number of documents.", `"$skip": \${1:0}`),
+ op("$lookup", "stage", "Performs a left outer join to another collection.", `"$lookup": { "from": "\${1:coll}", "localField": "\${2:local}", "foreignField": "\${3:foreign}", "as": "\${4:joined}" }`),
+ op("$unwind", "stage", "Deconstructs an array field into one document per element.", `"$unwind": "$\${1:field}"`),
+ op("$addFields", "stage", "Adds new fields to documents.", `"$addFields": \${1:{}}`),
+ op("$count", "stage", "Counts documents at this stage.", `"$count": "\${1:count}"`),
+ // accumulators
+ op("$sum", "accumulator", "Sums numeric values (use 1 to count).", `"$sum": \${1:1}`),
+ op("$avg", "accumulator", "Averages numeric values.", `"$avg": "$\${1:field}"`),
+ op("$min", "accumulator", "Returns the minimum value.", `"$min": "$\${1:field}"`),
+ op("$max", "accumulator", "Returns the maximum value.", `"$max": "$\${1:field}"`),
+ op("$first", "accumulator", "Returns the first value in a group.", `"$first": "$\${1:field}"`),
+ op("$last", "accumulator", "Returns the last value in a group.", `"$last": "$\${1:field}"`),
+ op("$push", "accumulator", "Appends values to an array in a group.", `"$push": "$\${1:field}"`),
+ op("$addToSet", "accumulator", "Appends unique values to an array in a group.", `"$addToSet": "$\${1:field}"`),
+];
+
+// Whole-query / whole-pipeline templates. These replace the editor content so
+// they carry no leading key — they are full JSON documents/arrays.
+export const MONGO_SNIPPETS: NosqlCompletion[] = [
+ tpl("find: equals", "Filter by a field equals a value.", `{ "\${1:field}": \${2:value} }`),
+ tpl("find: range", "Filter by a numeric/date range.", `{ "\${1:field}": { "$gte": \${2:min}, "$lte": \${3:max} } }`),
+ tpl("find: in list", "Field matches any value in a list.", `{ "\${1:field}": { "$in": [\${2:a}, \${3:b}] } }`),
+ tpl("find: regex", "Case-insensitive substring match.", `{ "\${1:field}": { "$regex": "\${2:text}", "$options": "i" } }`),
+ tpl("find: exists", "Field is present (or absent).", `{ "\${1:field}": { "$exists": \${2:true} } }`),
+ tpl("find: and", "Combine conditions with AND.", `{ "$and": [ { "\${1:a}": \${2:1} }, { "\${3:b}": \${4:2} } ] }`),
+ tpl("find: or", "Combine conditions with OR.", `{ "$or": [ { "\${1:a}": \${2:1} }, { "\${3:b}": \${4:2} } ] }`),
+ tpl("find: by ObjectId", "Match an _id ObjectId.", `{ "_id": { "$oid": "\${1:507f1f77bcf86cd799439011}" } }`),
+ tpl(
+ "agg: group + count",
+ "Group by a field and count documents per group.",
+ `[\n { "$group": { "_id": "$\${1:field}", "count": { "$sum": 1 } } },\n { "$sort": { "count": -1 } }\n]`,
+ ),
+ tpl(
+ "agg: group + sum/avg",
+ "Group and total/average a numeric field.",
+ `[\n { "$group": { "_id": "$\${1:groupField}", "total": { "$sum": "$\${2:amount}" }, "avg": { "$avg": "$\${2:amount}" } } }\n]`,
+ ),
+ tpl(
+ "agg: match + sort + limit",
+ "Top-N filtered documents.",
+ `[\n { "$match": { "\${1:field}": \${2:value} } },\n { "$sort": { "\${3:sortField}": -1 } },\n { "$limit": \${4:10} }\n]`,
+ ),
+ tpl(
+ "agg: lookup (join)",
+ "Left outer join to another collection.",
+ `[\n { "$lookup": { "from": "\${1:other}", "localField": "\${2:local}", "foreignField": "\${3:_id}", "as": "\${4:joined}" } },\n { "$unwind": "$\${4:joined}" }\n]`,
+ ),
+ tpl(
+ "agg: unwind + group",
+ "Flatten an array then group by its elements.",
+ `[\n { "$unwind": "$\${1:items}" },\n { "$group": { "_id": "$\${1:items}", "count": { "$sum": 1 } } }\n]`,
+ ),
+ tpl(
+ "agg: facet",
+ "Run multiple sub-pipelines in one pass.",
+ `[\n { "$facet": {\n "\${1:byStatus}": [ { "$group": { "_id": "$\${2:status}", "n": { "$sum": 1 } } } ],\n "\${3:total}": [ { "$count": "count" } ]\n } }\n]`,
+ ),
+];
+
+function op(label: string, detail: string, doc: string, body: string): NosqlCompletion {
+ return { label, detail, doc, insertText: body, snippet: true };
+}
+
+function tpl(label: string, doc: string, body: string): NosqlCompletion {
+ return { label, detail: "snippet", doc, insertText: body, snippet: true };
+}
diff --git a/apps/desktop-ui/src/lib/seo/comparison-pages.ts b/apps/desktop-ui/src/lib/seo/comparison-pages.ts
deleted file mode 100644
index f2d27324..00000000
--- a/apps/desktop-ui/src/lib/seo/comparison-pages.ts
+++ /dev/null
@@ -1,954 +0,0 @@
-export type ComparisonPage = {
- slug: string
- title: string
- description: string
- eyebrow: string
- heading: string
- intro: string
- competitor?: string
- toolSlug?: string
- primaryCta: { href: string; label: string }
- sections: Array<{
- title: string
- body: string
- bullets: string[]
- }>
- faqs: Array<{ q: string; a: string }>
-}
-
-export const comparisonPages: ComparisonPage[] = [
- {
- slug: 'best-online-developer-tools',
- title: 'Best Online Developer Tools',
- description:
- 'Compare MyDevTools with single-purpose online developer tools and see why a unified, open-source developer toolkit is better for everyday engineering workflows.',
- eyebrow: 'Best Developer Tools',
- heading: 'Best online developer tools for fast browser-based workflows',
- intro:
- 'Most developers collect dozens of single-purpose formatter, decoder, generator, and API testing websites. MyDevTools brings those daily utilities into one searchable toolkit with public tool pages, an app dashboard, and a self-hostable open-source codebase.',
- primaryCta: { href: '/tools', label: 'Browse MyDevTools' },
- sections: [
- {
- title: 'Why a toolkit beats a bookmark folder',
- body:
- 'Single-purpose sites are useful, but they create tab sprawl and inconsistent privacy expectations. A unified toolkit gives developers one place to start.',
- bullets: [
- 'Use JSON, JWT, regex, UUID, Base64, API, hashing, timestamp, and generator tools from one domain.',
- 'Move between related utilities without searching for another website.',
- 'Use public landing pages for discovery and the app dashboard for daily work.',
- ],
- },
- {
- title: 'When single-purpose tools still win',
- body:
- 'A dedicated website can be best when it has one highly specialized feature, a familiar interface, or team muscle memory.',
- bullets: [
- 'Use regex101 when you need its specific regex explanation workflow.',
- 'Use Postman or Insomnia when you need full team API lifecycle management.',
- 'Use MyDevTools when you need broad, fast browser utilities in one open-source workspace.',
- ],
- },
- {
- title: 'Why developers choose MyDevTools',
- body:
- 'MyDevTools is strongest as an everyday browser toolkit for quick operations, learning, debugging, and self-hosted control.',
- bullets: [
- 'Open-source GPL-3.0 codebase for auditability.',
- 'Public SEO pages for each tool, plus authenticated workspace features when needed.',
- 'Self-hosting path for developers and teams that want infrastructure control.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Is MyDevTools a replacement for every developer tool?',
- a: 'No. It is best for everyday browser-based utilities and quick workflows. Specialized desktop or enterprise tools can still be better for deep team workflows.',
- },
- {
- q: 'Why use MyDevTools instead of separate tool websites?',
- a: 'It reduces context switching and gives you one searchable toolkit for common developer tasks like formatting JSON, decoding JWTs, testing regexes, generating UUIDs, and more.',
- },
- ],
- },
- {
- slug: 'mydevtools-vs-jsonformatter-org',
- title: 'MyDevTools vs JSONFormatter.org',
- description:
- 'Compare MyDevTools with JSONFormatter.org for JSON formatting, validation, and broader developer toolkit workflows.',
- eyebrow: 'Comparison',
- heading: 'MyDevTools vs JSONFormatter.org',
- intro:
- 'JSONFormatter.org is useful for focused JSON formatting. MyDevTools includes JSON formatting as part of a broader online developer toolkit for API, encoding, security, generator, and productivity workflows.',
- competitor: 'JSONFormatter.org',
- toolSlug: 'json-formatter',
- primaryCta: { href: '/tools/json-formatter', label: 'Try JSON Formatter' },
- sections: [
- {
- title: 'Choose JSONFormatter.org when',
- body:
- 'A single-purpose JSON formatter can be enough for a quick paste, format, and copy workflow.',
- bullets: [
- 'You only need to format or inspect JSON.',
- 'You already know its interface and do not need other developer utilities.',
- 'You do not need an open-source toolkit or self-hosting path.',
- ],
- },
- {
- title: 'Choose MyDevTools when',
- body:
- 'JSON work rarely happens alone. Developers often need to decode tokens, inspect URLs, test APIs, generate IDs, compare diffs, and transform formats in the same session.',
- bullets: [
- 'Use JSON formatting alongside JWT, API client, URL parser, Base64, hash, UUID, and mock data tools.',
- 'Stay in one browser-based developer toolkit instead of opening multiple unrelated sites.',
- 'Self-host the open-source codebase when you want control over the environment.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'Use JSONFormatter.org for a narrowly focused JSON task. Use MyDevTools when JSON formatting is one part of a larger developer workflow.',
- bullets: [
- 'Best single-purpose fit: JSONFormatter.org.',
- 'Best multi-tool workflow fit: MyDevTools.',
- 'Best open-source/self-hostable option: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Does MyDevTools include a JSON formatter?',
- a: 'Yes. MyDevTools includes a JSON formatter/editor landing page and app tool, plus related tools for JWT, APIs, URLs, Base64, diffs, and schema workflows.',
- },
- {
- q: 'Is MyDevTools only for JSON?',
- a: 'No. JSON is one tool in a larger online developer toolkit with 50+ utilities.',
- },
- ],
- },
- {
- slug: 'mydevtools-vs-jwt-io',
- title: 'MyDevTools vs jwt.io',
- description:
- 'Compare MyDevTools with jwt.io for JWT decoding and broader browser-based security and developer workflows.',
- eyebrow: 'Comparison',
- heading: 'MyDevTools vs jwt.io',
- intro:
- 'jwt.io is a well-known JWT debugger. MyDevTools includes JWT decoding as part of a broader developer toolkit for tokens, certificates, hashing, HMAC, encryption, API requests, and data formatting.',
- competitor: 'jwt.io',
- toolSlug: 'jwt-decoder',
- primaryCta: { href: '/tools/jwt-decoder', label: 'Try JWT Decoder' },
- sections: [
- {
- title: 'Choose jwt.io when',
- body:
- 'jwt.io is familiar and focused for quickly reading JWT header and payload fields.',
- bullets: [
- 'You want a dedicated JWT debugger experience.',
- 'Your workflow is limited to token inspection.',
- 'Your team already references jwt.io in documentation.',
- ],
- },
- {
- title: 'Choose MyDevTools when',
- body:
- 'JWT debugging often connects to API testing, timestamp inspection, hashing, HMAC signatures, and certificate review.',
- bullets: [
- 'Decode JWTs and then test API calls in the same toolkit.',
- 'Use timestamp, HMAC, hash, certificate, and encryption tools nearby.',
- 'Use an open-source, self-hostable developer toolkit for broader security workflows.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'jwt.io is strong for a familiar dedicated JWT page. MyDevTools is stronger when JWT decoding is one step in a broader developer or API workflow.',
- bullets: [
- 'Best dedicated JWT page: jwt.io.',
- 'Best multi-step API/security workflow: MyDevTools.',
- 'Best self-hostable option: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Can MyDevTools decode JWTs?',
- a: 'Yes. The JWT Decoder lets you inspect JWT header and payload fields in the browser.',
- },
- {
- q: 'Does MyDevTools verify JWT signatures?',
- a: 'The JWT tool is focused on decoding and inspection. For signature-related workflows, pair it with HMAC, hashing, certificate, or API testing tools as needed.',
- },
- ],
- },
- {
- slug: 'mydevtools-vs-regex101',
- title: 'MyDevTools vs regex101',
- description:
- 'Compare MyDevTools with regex101 for regex testing and broader online developer toolkit workflows.',
- eyebrow: 'Comparison',
- heading: 'MyDevTools vs regex101',
- intro:
- 'regex101 is excellent for deep regex explanation and pattern sharing. MyDevTools includes regex testing as part of a larger online toolkit for formatting, parsing, generating, and debugging developer data.',
- competitor: 'regex101',
- toolSlug: 'regex-tester',
- primaryCta: { href: '/tools/regex-tester', label: 'Try Regex Tester' },
- sections: [
- {
- title: 'Choose regex101 when',
- body:
- 'A specialized regex site is best when you need detailed explanations, flavor-specific behavior, and pattern sharing.',
- bullets: [
- 'You need advanced regex explanations.',
- 'You want a dedicated regex-focused workspace.',
- 'You are debugging a complex expression in depth.',
- ],
- },
- {
- title: 'Choose MyDevTools when',
- body:
- 'Regex testing is often part of larger cleanup or validation work with URLs, JSON payloads, logs, encoded strings, and generated test data.',
- bullets: [
- 'Test regex patterns alongside JSON, URL, Base64, timestamp, and mock data tools.',
- 'Use one browser toolkit for common developer utilities.',
- 'Self-host the toolkit for internal workflows.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'Use regex101 for deep regex education and explanation. Use MyDevTools when regex testing is part of a broader development task.',
- bullets: [
- 'Best advanced regex explanation: regex101.',
- 'Best multi-tool developer workflow: MyDevTools.',
- 'Best open-source toolkit context: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Does MyDevTools have a regex tester?',
- a: 'Yes. MyDevTools includes an online regex tester for checking JavaScript regular expressions in the browser.',
- },
- {
- q: 'Is MyDevTools better than regex101?',
- a: 'It depends. regex101 is stronger for advanced regex explanation. MyDevTools is better when regex testing is one part of a broader developer toolkit workflow.',
- },
- ],
- },
- {
- slug: 'cyberchef-alternative',
- title: 'CyberChef Alternative',
- description:
- 'Looking for a CyberChef alternative for everyday browser developer utilities? Compare MyDevTools for formatting, decoding, encoding, hashing, and generator workflows.',
- eyebrow: 'Alternative',
- heading: 'CyberChef alternative for everyday developer workflows',
- intro:
- 'CyberChef is powerful for chained transformations and forensic-style recipes. MyDevTools is built for everyday developer utility workflows: format JSON, decode JWTs, encode Base64, hash data, parse URLs, generate UUIDs, and test APIs from one toolkit.',
- competitor: 'CyberChef',
- primaryCta: { href: '/tools', label: 'Browse MyDevTools' },
- sections: [
- {
- title: 'Choose CyberChef when',
- body:
- 'CyberChef is excellent for chaining operations, recipes, analysis, and advanced transformation workflows.',
- bullets: [
- 'You need multi-step transformation recipes.',
- 'You work on forensic or security analysis tasks.',
- 'You need the specific CyberChef operation model.',
- ],
- },
- {
- title: 'Choose MyDevTools when',
- body:
- 'MyDevTools is aimed at common engineering workflows where you want named tools, landing pages, app navigation, and self-hosted control.',
- bullets: [
- 'Use dedicated tools for JSON, JWT, regex, UUID, Base64, hashing, timestamps, and APIs.',
- 'Keep everyday developer utilities discoverable in one dashboard.',
- 'Use an open-source toolkit designed for general developer productivity.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'CyberChef is best for advanced chained operations. MyDevTools is best as a broad daily developer toolkit.',
- bullets: [
- 'Best recipe-based transformations: CyberChef.',
- 'Best everyday developer toolkit: MyDevTools.',
- 'Best product-style tool directory: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Is MyDevTools a CyberChef clone?',
- a: 'No. MyDevTools focuses on individual developer utilities and a unified dashboard rather than recipe-based chained operations.',
- },
- {
- q: 'When should I use MyDevTools instead of CyberChef?',
- a: 'Use MyDevTools for common developer tasks like formatting JSON, decoding JWTs, testing APIs, generating UUIDs, hashing values, and parsing URLs.',
- },
- ],
- },
- {
- slug: 'postman-alternative-online',
- title: 'Online Postman Alternative',
- description:
- 'Compare MyDevTools as a lightweight online Postman alternative for quick API testing alongside JSON, JWT, URL, encoding, and generator tools.',
- eyebrow: 'Alternative',
- heading: 'Online Postman alternative for quick API testing',
- intro:
- 'Postman is a full API platform. MyDevTools is a lightweight online developer toolkit with an API client plus surrounding utilities developers often need during API debugging.',
- competitor: 'Postman',
- toolSlug: 'api-client',
- primaryCta: { href: '/tools/api-client', label: 'Try API Client' },
- sections: [
- {
- title: 'Choose Postman when',
- body:
- 'Postman is better for full API lifecycle management, team collaboration, mock servers, collections, and governance.',
- bullets: [
- 'You need enterprise API collaboration.',
- 'You manage large shared API collections.',
- 'You rely on Postman-specific test automation and governance.',
- ],
- },
- {
- title: 'Choose MyDevTools when',
- body:
- 'Sometimes you just need to send a request, inspect a response, decode a token, format JSON, and generate test data without opening a heavy desktop workflow.',
- bullets: [
- 'Use the API client for quick request testing.',
- 'Pair API testing with JSON, JWT, URL, Base64, timestamp, and mock data tools.',
- 'Use the browser-based toolkit when speed and context switching matter more than enterprise API management.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'Postman is stronger as a full API platform. MyDevTools is useful as a fast online toolkit around lightweight API debugging.',
- bullets: [
- 'Best enterprise API platform: Postman.',
- 'Best quick browser toolkit around API debugging: MyDevTools.',
- 'Best open-source self-hostable toolkit path: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Is MyDevTools a full Postman replacement?',
- a: 'No. MyDevTools is better described as a lightweight online API client inside a broader developer toolkit.',
- },
- {
- q: 'Why use MyDevTools for API debugging?',
- a: 'It keeps API requests close to related tools like JSON formatter, JWT decoder, URL parser, timestamp converter, and mock data generator.',
- },
- ],
- },
- {
- slug: 'mydevtools-vs-postman',
- title: 'MyDevTools vs Postman',
- description:
- 'Compare MyDevTools with Postman for browser-based API testing, developer utilities, JSON formatting, JWT decoding, and lightweight request debugging.',
- eyebrow: 'Comparison',
- heading: 'MyDevTools vs Postman: lightweight browser API testing',
- intro:
- 'Postman is a full API platform for teams, collections, environments, and API lifecycle workflows. MyDevTools is a browser-based developer toolkit with a lightweight API client plus JSON, JWT, URL, timestamp, mock data, and security tools for quick debugging sessions.',
- competitor: 'Postman',
- toolSlug: 'api-client',
- primaryCta: { href: '/tools/api-client', label: 'Try API Client' },
- sections: [
- {
- title: 'Choose Postman when',
- body:
- 'Postman is strongest when API work is a team process with shared collections, governance, documentation, mock servers, and automated tests.',
- bullets: [
- 'You need a complete API lifecycle platform.',
- 'Your team collaborates on large shared request collections.',
- 'You rely on Postman-specific environments, monitors, and governance features.',
- ],
- },
- {
- title: 'Choose MyDevTools when',
- body:
- 'MyDevTools is better for quick browser-based debugging where an API request is only one part of a larger utility workflow.',
- bullets: [
- 'Send a request, format the JSON response, decode a JWT, and parse URLs in the same toolkit.',
- 'Use a lightweight browser workflow without installing a desktop API client.',
- 'Self-host the open-source toolkit if you need internal access and infrastructure control.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'Postman remains the better full API platform. MyDevTools is the better lightweight browser alternative for quick API debugging plus surrounding developer utilities.',
- bullets: [
- 'Best enterprise API platform: Postman.',
- 'Best browser-based quick API workflow: MyDevTools.',
- 'Best API client plus 50+ utility toolkit: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Is MyDevTools a Postman replacement?',
- a: 'Not for full enterprise API lifecycle management. MyDevTools is a lightweight online alternative when you need quick API requests plus related developer tools.',
- },
- {
- q: 'What makes MyDevTools useful for API debugging?',
- a: 'API debugging often requires formatting JSON, decoding JWTs, parsing URLs, converting timestamps, and generating mock data. MyDevTools keeps those tools near the API client.',
- },
- ],
- },
- {
- slug: 'uuid-generator-online',
- title: 'Best Free UUID Generator Online',
- description:
- 'Generate UUID v4, v7, and other versions instantly in your browser. Compare online UUID generators and learn when to use each UUID version.',
- eyebrow: 'UUID Generator',
- heading: 'Best free online UUID generator: v4, v7, bulk generation',
- intro:
- 'Most UUID generator sites produce a single v4 UUID. MyDevTools UUID Generator lets you choose the version (v4, v7, ULID), generate in bulk, and stay inside a broader developer toolkit for API keys, hashing, QR codes, and other generator workflows.',
- toolSlug: 'uuid-generator',
- primaryCta: { href: '/tools/uuid-generator', label: 'Generate UUIDs' },
- sections: [
- {
- title: 'UUID v4 vs v7: which to generate',
- body:
- 'UUID v4 is fully random and works everywhere. UUID v7 is time-ordered, which makes it better for database primary keys where insert order matters for index performance.',
- bullets: [
- 'UUID v4: stateless, random, maximum compatibility with existing systems.',
- 'UUID v7: time-ordered, better B-tree locality, recommended for new database schemas.',
- 'ULID: shorter, URL-safe, lexicographically sortable alternative to UUID.',
- ],
- },
- {
- title: 'Why use a toolkit instead of a single-purpose generator',
- body:
- 'After generating UUIDs you often need to build a request body, format JSON, or generate an API key — all in the same session.',
- bullets: [
- 'Generate UUIDs and API keys from the same generator section.',
- 'Paste generated IDs into the API client or JSON formatter without switching tabs.',
- 'Use mock data generator when you need multiple IDs alongside other test fields.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'Any UUID generator produces valid v4 UUIDs. Choose one that integrates into your broader workflow.',
- bullets: [
- 'Best single v4: any online generator.',
- 'Best version choice + bulk + context: MyDevTools.',
- 'Best open-source/self-hosted: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Is it safe to use an online UUID generator?',
- a: 'UUID v4 generators use cryptographically random bytes and do not transmit anything sensitive. MyDevTools UUID Generator runs in your browser with no server round-trip.',
- },
- {
- q: 'Can I generate UUIDs in bulk online?',
- a: 'Yes. MyDevTools UUID Generator lets you set a count and generate multiple UUIDs at once, ready to copy as a list.',
- },
- ],
- },
- {
- slug: 'base64-encoder-decoder-online',
- title: 'Free Online Base64 Encoder and Decoder',
- description:
- 'Encode text or binary to Base64 and decode Base64 back to text instantly in your browser. Compare online Base64 tools and understand when to use Base64URL.',
- eyebrow: 'Base64 Encoder',
- heading: 'Free online Base64 encoder and decoder — text, file, and URL-safe',
- intro:
- 'Base64 encoding is a daily task for developers working with APIs, JWTs, images, and authentication headers. MyDevTools Base64 tool handles standard encoding, URL-safe Base64, and file input — all in the browser, no install.',
- toolSlug: 'base64',
- primaryCta: { href: '/tools/base64', label: 'Open Base64 Tool' },
- sections: [
- {
- title: 'Standard Base64 vs Base64URL',
- body:
- 'Standard Base64 uses + and / which are unsafe in URLs. Base64URL substitutes - and _ and drops padding — essential for JWTs, OAuth tokens, and URL query parameters.',
- bullets: [
- 'Standard Base64: use for email attachments, binary in JSON, image data URIs.',
- 'Base64URL: use for JWTs, URL parameters, and any context where + and / break parsing.',
- 'MyDevTools Base64 tool handles both modes in one place.',
- ],
- },
- {
- title: 'When Base64 encoding appears in developer workflows',
- body:
- 'Base64 shows up in API authentication, JWT payloads, data URIs, and binary field serialization.',
- bullets: [
- 'HTTP Basic Auth encodes credentials as Base64 in the Authorization header.',
- 'JWT header and payload are Base64URL-encoded sections.',
- 'Image data URIs embed Base64-encoded bytes directly in HTML or CSS.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'Any online Base64 encoder produces correct output for text input. MyDevTools adds file input, URL-safe mode, and related tools in one place.',
- bullets: [
- 'Best for text encoding: any online tool.',
- 'Best for file + URL-safe + toolkit context: MyDevTools.',
- 'Best open-source option: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Is Base64 the same as encryption?',
- a: 'No. Base64 is a reversible encoding that anyone can decode without a key. Use it to make binary data text-safe, not to protect secrets.',
- },
- {
- q: 'Why does my Base64 output end with == ?',
- a: 'Base64 works on 3-byte groups. = padding fills out the last group when the input length is not divisible by 3.',
- },
- ],
- },
- {
- slug: 'online-diff-checker',
- title: 'Online Diff Checker — Compare Text, Code, and JSON',
- description:
- 'Compare two blocks of text, code, or JSON side by side and highlight differences instantly in the browser. Find the best online diff tool for your workflow.',
- eyebrow: 'Diff Checker',
- heading: 'Online diff checker: compare text, code, and JSON side by side',
- intro:
- 'Online diff tools let you paste two versions of a file and instantly see additions, deletions, and changes highlighted. MyDevTools Diff Checker works in the browser alongside JSON formatting, URL parsing, and other utilities developers use in the same session.',
- toolSlug: 'diff-checker',
- primaryCta: { href: '/tools/diff-checker', label: 'Try Diff Checker' },
- sections: [
- {
- title: 'When to use an online diff checker',
- body:
- 'Online diff is fastest for one-off comparisons: reviewing a config change, checking a response before and after a fix, or comparing two API payloads.',
- bullets: [
- 'Compare JSON responses before and after an API change.',
- 'Check .env files or config differences without a local IDE.',
- 'Review copied text for hidden differences (whitespace, encoding).',
- ],
- },
- {
- title: 'When to use a local diff tool',
- body:
- 'For large files, version history, and repository diffs, local tools like git diff or VS Code built-in diff are better suited.',
- bullets: [
- 'Use git diff for code review of committed changes.',
- 'Use VS Code diff for large files where browser performance matters.',
- 'Use online diff for quick one-off comparisons without opening a project.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'Online diff checkers are best for quick, one-off comparisons. MyDevTools adds JSON formatting and related tools in the same workspace.',
- bullets: [
- 'Best for quick text/JSON diff: MyDevTools or diffchecker.com.',
- 'Best for repository diffs: git diff / VS Code.',
- 'Best for open-source browser toolkit: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Can I diff JSON with an online diff checker?',
- a: 'Yes. Paste two JSON objects and the diff checker highlights the changed fields line by line. For better readability, format the JSON first using the JSON formatter.',
- },
- {
- q: 'Is my text safe in an online diff tool?',
- a: 'MyDevTools Diff Checker runs the comparison in your browser with no server upload. Avoid pasting credentials or private keys into any online tool.',
- },
- ],
- },
- {
- slug: 'hash-generator-online',
- title: 'Online Hash Generator — MD5, SHA-1, SHA-256, SHA-512',
- description:
- 'Generate MD5, SHA-1, SHA-256, and SHA-512 hashes from any text instantly in your browser. Compare online hash generators and understand which algorithm to use.',
- eyebrow: 'Hash Generator',
- heading: 'Online hash generator: MD5, SHA-1, SHA-256, SHA-512 in the browser',
- intro:
- 'Hashing is used for checksums, data integrity verification, password storage (with salt), API signatures, and fingerprinting content. MyDevTools Hash Generator runs all major algorithms in the browser without sending your data to a server.',
- toolSlug: 'hash-generator',
- primaryCta: { href: '/tools/hash-generator', label: 'Generate Hashes' },
- sections: [
- {
- title: 'Which hash algorithm to use',
- body:
- 'Algorithm choice depends on the use case. MD5 and SHA-1 are broken for security purposes but still used for checksums. SHA-256 and SHA-512 are the current standard for security-sensitive contexts.',
- bullets: [
- 'MD5: file checksums, cache keys, non-security fingerprinting only.',
- 'SHA-1: deprecated for TLS and signing; avoid for new security work.',
- 'SHA-256: standard for HMAC, JWT signatures, data integrity, and API auth.',
- 'SHA-512: higher security margin; used when SHA-256 feels insufficient for the threat model.',
- ],
- },
- {
- title: 'Hash generator vs HMAC generator',
- body:
- 'A plain hash has no secret key and is not authentication-safe. HMAC (Hash-based Message Authentication Code) combines hashing with a secret key, making it resistant to length-extension attacks and safe for API authentication.',
- bullets: [
- 'Use hash for checksums and content fingerprinting.',
- 'Use HMAC for API request signing, webhook signature verification, and authentication.',
- 'MyDevTools has both a Hash Generator and a dedicated HMAC Generator.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'Any online hash tool generates correct hashes. MyDevTools adds HMAC, encryption, JWT, and password tools in the same security-focused section.',
- bullets: [
- 'Best single-hash generation: any online tool.',
- 'Best hash + HMAC + encryption toolkit: MyDevTools.',
- 'Best open-source option: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Is MD5 still safe to use?',
- a: 'MD5 is broken for cryptographic security — collisions can be generated. It is still acceptable for non-security purposes like cache keys and file checksums. Never use MD5 for password hashing or digital signatures.',
- },
- {
- q: 'Can I reverse a hash to get the original text?',
- a: 'No. Hashing is a one-way function. You cannot reverse a hash to recover the original input — only compare it against a known hash of a candidate input.',
- },
- ],
- },
- {
- slug: 'mydevtools-vs-transform-tools',
- title: 'MyDevTools vs transform.tools',
- description:
- 'Compare MyDevTools with transform.tools for data conversion and transformation workflows. See which tool fits everyday developer needs.',
- eyebrow: 'Comparison',
- heading: 'MyDevTools vs transform.tools',
- intro:
- 'transform.tools offers a focused set of data transformation utilities. MyDevTools covers data conversion as part of a broader developer toolkit that also includes API testing, security tools, generators, and productivity features.',
- competitor: 'transform.tools',
- primaryCta: { href: '/tools', label: 'Browse MyDevTools' },
- sections: [
- {
- title: 'Choose transform.tools when',
- body:
- 'transform.tools is a clean, purpose-built site for specific format transformations.',
- bullets: [
- 'You need specific transforms like JSON to TypeScript or GraphQL to Flow.',
- 'You want a focused single-purpose interface.',
- 'Your workflow is entirely about converting between data formats.',
- ],
- },
- {
- title: 'Choose MyDevTools when',
- body:
- 'Transformations are rarely isolated. Most developers also need to format, validate, test an API, decode a token, or generate test data in the same session.',
- bullets: [
- 'Use format converter, JSON formatter, and CSV tools alongside API client and JWT decoder.',
- 'Stay in one toolkit instead of bookmarking 10 different sites.',
- 'Self-host the open-source codebase for team or internal use.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'transform.tools wins for narrow format conversion tasks. MyDevTools wins when conversions are part of a broader development workflow.',
- bullets: [
- 'Best narrow data transformation: transform.tools.',
- 'Best broad developer toolkit: MyDevTools.',
- 'Best open-source self-hostable option: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Does MyDevTools support JSON to TypeScript conversion?',
- a: 'MyDevTools includes a JSON Schema Generator that infers schema from JSON. For direct JSON-to-TypeScript type generation, pair it with the JSON formatter to clean the input first.',
- },
- {
- q: 'Is MyDevTools open source like transform.tools?',
- a: 'Yes. MyDevTools is open source under GPL-3.0. You can inspect, fork, and self-host the entire codebase.',
- },
- ],
- },
- {
- slug: 'qr-code-generator-online',
- title: 'Free Online QR Code Generator',
- description:
- 'Generate QR codes from URLs, text, or contact info instantly in your browser. No watermarks, no account required. Download as PNG or SVG.',
- eyebrow: 'QR Code Generator',
- heading: 'Free online QR code generator: URL, text, vCard — download as PNG or SVG',
- intro:
- 'QR code generators are a common developer utility for sharing links, embedding URLs in print materials, and testing mobile deep links. MyDevTools QR Code Generator runs in the browser with no ads, no watermarks, and no account required.',
- toolSlug: 'qr-code-generator',
- primaryCta: { href: '/tools/qr-code-generator', label: 'Generate QR Code' },
- sections: [
- {
- title: 'What to look for in a QR code generator',
- body:
- 'Most online generators add watermarks or require sign-up for PNG downloads. Browser-based generation avoids the data being sent to a third-party server.',
- bullets: [
- 'No watermarks on downloaded codes.',
- 'No account required for basic generation.',
- 'Runs locally so no URL or text data is transmitted to a backend.',
- ],
- },
- {
- title: 'QR code use cases for developers',
- body:
- 'Developers generate QR codes for testing mobile deep links, embedding URLs in documentation, sharing Wi-Fi credentials, and linking print materials to web resources.',
- bullets: [
- 'Test mobile app deep links by scanning QR codes during development.',
- 'Embed a URL QR code in slides, docs, or print without a design tool.',
- 'Share a staging URL quickly with a phone scan instead of typing.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'Any browser-based QR generator works for basic needs. MyDevTools adds QR generation alongside API client, URL parser, and other daily developer tools in one workspace.',
- bullets: [
- 'Best for quick generation: MyDevTools or qr-code-generator.com.',
- 'Best for developer toolkit context: MyDevTools.',
- 'Best open-source option: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Are QR codes generated online safe?',
- a: 'The safety concern is whether your URL or text is sent to a server. MyDevTools QR Code Generator renders the code in your browser using a local library — your input is not transmitted.',
- },
- {
- q: 'What file formats can I download QR codes in?',
- a: 'MyDevTools QR Code Generator supports PNG download. SVG output preserves crispness at any print size.',
- },
- ],
- },
- {
- slug: 'mydevtools-vs-it-tools-tech',
- title: 'MyDevTools vs it-tools.tech',
- description:
- 'Compare MyDevTools with it-tools.tech for browser-based developer utilities, self-hosting, tool coverage, and everyday workflow fit.',
- eyebrow: 'Comparison',
- heading: 'MyDevTools vs it-tools.tech',
- intro:
- 'it-tools.tech is a strong open-source collection of developer utilities. MyDevTools targets similar daily developer needs while adding product-style landing pages, workspace flows, cloud/self-host positioning, and tools such as API, database, productivity, and secure sync workflows.',
- competitor: 'it-tools.tech',
- primaryCta: { href: '/developer-tools', label: 'Explore MyDevTools' },
- sections: [
- {
- title: 'Choose it-tools.tech when',
- body:
- 'it-tools.tech is excellent when you want a lightweight open-source utility collection with many simple browser tools.',
- bullets: [
- 'You want a familiar open-source utility collection.',
- 'You only need local single-purpose transforms and generators.',
- 'You prefer its exact tool catalog and interface.',
- ],
- },
- {
- title: 'Choose MyDevTools when',
- body:
- 'MyDevTools is a better fit when you want a broader product experience around daily development tasks, public tool pages, and optional account-backed workflows.',
- bullets: [
- 'Use API, database, productivity, formatter, converter, generator, and security tools together.',
- 'Use public /tools pages for discovery and a dashboard for daily use.',
- 'Self-host the codebase or use the managed cloud path.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'Both projects are useful. it-tools.tech is a focused utility collection; MyDevTools is positioned as a broader open-source developer tools platform.',
- bullets: [
- 'Best lightweight utility collection: it-tools.tech.',
- 'Best broader developer tools platform: MyDevTools.',
- 'Best mixed cloud/self-host product direction: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Is MyDevTools an alternative to it-tools.tech?',
- a: 'Yes. MyDevTools overlaps on many browser-based utility workflows while also adding a broader dashboard, public landing pages, and additional developer productivity tools.',
- },
- {
- q: 'Are both projects open source?',
- a: 'Yes. Both are open-source developer tool projects, but their tool catalogs and product direction differ.',
- },
- ],
- },
- {
- slug: 'mydevtools-vs-it-tools',
- title: 'MyDevTools vs IT Tools',
- description:
- 'Compare MyDevTools with IT Tools / it-tools.tech for online developer utilities, self-hosting, tool coverage, and browser-based workflows.',
- eyebrow: 'Comparison',
- heading: 'MyDevTools vs IT Tools: open-source developer utility platforms',
- intro:
- 'IT Tools (it-tools.tech) is a popular open-source collection of browser utilities. MyDevTools targets the same everyday developer utility need while adding public tool landing pages, dashboard flows, cloud/self-host positioning, and a broader product surface.',
- competitor: 'IT Tools',
- primaryCta: { href: '/developer-tools', label: 'Explore MyDevTools' },
- sections: [
- {
- title: 'Choose IT Tools when',
- body:
- 'IT Tools is excellent when you want a focused utility collection with many small local tools and a familiar open-source interface.',
- bullets: [
- 'You want a lightweight collection of one-off utilities.',
- 'You prefer the exact it-tools.tech catalog and layout.',
- 'You only need quick local transforms, encoders, decoders, and generators.',
- ],
- },
- {
- title: 'Choose MyDevTools when',
- body:
- 'MyDevTools is built as a broader developer tools platform with public SEO pages, app dashboard, self-hosting, and optional cloud workflows.',
- bullets: [
- 'Use utilities plus API, database, productivity, security, and sync-oriented workflows.',
- 'Link to canonical /tools pages for each utility.',
- 'Self-host or use managed cloud depending on your deployment preference.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'Both are useful open-source developer utility platforms. IT Tools is strongest as a focused utility collection; MyDevTools is strongest as a broader developer tools product.',
- bullets: [
- 'Best simple utility collection: IT Tools.',
- 'Best broader platform and content structure: MyDevTools.',
- 'Best cloud/self-host product path: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Is MyDevTools an IT Tools alternative?',
- a: 'Yes. MyDevTools overlaps with many browser utility workflows while adding a broader dashboard, public tool pages, and product-oriented platform pages.',
- },
- {
- q: 'Which is better for self-hosting?',
- a: 'Both can fit self-hosting workflows. MyDevTools emphasizes self-hosting as a core product path alongside managed cloud.',
- },
- ],
- },
- {
- slug: 'mydevtools-vs-devutils-app',
- title: 'MyDevTools vs DevUtils.app',
- description:
- 'Compare MyDevTools with DevUtils.app for developer utilities, browser-based tools, self-hosting, and cross-device workflows.',
- eyebrow: 'Comparison',
- heading: 'MyDevTools vs DevUtils.app',
- intro:
- 'DevUtils.app is a native Mac app for offline developer utilities. MyDevTools is browser-based, open-source, and self-hostable, making it easier to use across devices and operating systems without installing a desktop app.',
- competitor: 'DevUtils.app',
- primaryCta: { href: '/tools', label: 'Browse Browser Tools' },
- sections: [
- {
- title: 'Choose DevUtils.app when',
- body:
- 'A native desktop app is ideal when you want offline-first performance and a polished Mac-specific utility experience.',
- bullets: [
- 'You primarily work on macOS.',
- 'You prefer local desktop apps over browser tabs.',
- 'You want a native utility launcher for personal use.',
- ],
- },
- {
- title: 'Choose MyDevTools when',
- body:
- 'A browser-based toolkit is better when you switch machines, use multiple operating systems, or want a self-hostable web app.',
- bullets: [
- 'Open tools from any modern browser without installing a Mac app.',
- 'Use the same toolkit on macOS, Windows, Linux, or shared machines.',
- 'Self-host MyDevTools for internal team access.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'DevUtils.app wins for native Mac utility workflows. MyDevTools wins for browser access, self-hosting, and cross-device availability.',
- bullets: [
- 'Best native Mac utility app: DevUtils.app.',
- 'Best browser-based toolkit: MyDevTools.',
- 'Best self-hostable web option: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Is MyDevTools a DevUtils.app alternative?',
- a: 'Yes, for browser-based developer utility workflows. DevUtils.app remains stronger if you specifically want a native Mac app.',
- },
- {
- q: 'Does MyDevTools work on Windows and Linux?',
- a: 'Yes. MyDevTools runs in the browser, so it is not tied to macOS.',
- },
- ],
- },
- {
- slug: 'insomnia-alternative-online',
- title: 'Online Insomnia Alternative',
- description:
- 'Compare MyDevTools with Insomnia for lightweight browser-based API testing and surrounding developer utilities.',
- eyebrow: 'Alternative',
- heading: 'Online Insomnia alternative for lightweight API debugging',
- intro:
- 'Insomnia is a dedicated desktop API client. MyDevTools offers a lightweight browser API client alongside JSON, JWT, URL, timestamp, mock data, and security tools that are often needed during API debugging.',
- competitor: 'Insomnia',
- toolSlug: 'api-client',
- primaryCta: { href: '/tools/api-client', label: 'Try API Client' },
- sections: [
- {
- title: 'Choose Insomnia when',
- body:
- 'Insomnia is better for dedicated API development with desktop collections, environments, plugins, and team workflows.',
- bullets: [
- 'You need a full desktop API client.',
- 'You manage complex request collections.',
- 'Your team already standardizes on Insomnia.',
- ],
- },
- {
- title: 'Choose MyDevTools when',
- body:
- 'MyDevTools is useful for quick API debugging in a browser, especially when the request workflow connects to common utility tasks.',
- bullets: [
- 'Test API requests and then format JSON responses nearby.',
- 'Decode JWTs, parse URLs, convert timestamps, and generate mock data in one toolkit.',
- 'Use a browser-based tool when installing a desktop client is unnecessary.',
- ],
- },
- {
- title: 'Verdict',
- body:
- 'Insomnia is the better full API client. MyDevTools is a lightweight online alternative for quick debugging plus related developer utilities.',
- bullets: [
- 'Best dedicated desktop API client: Insomnia.',
- 'Best browser toolkit around API debugging: MyDevTools.',
- 'Best no-install quick workflow: MyDevTools.',
- ],
- },
- ],
- faqs: [
- {
- q: 'Is MyDevTools a full Insomnia replacement?',
- a: 'No. It is a lightweight browser-based API client inside a larger toolkit, not a complete desktop API platform.',
- },
- {
- q: 'Why use MyDevTools for API testing?',
- a: 'Use it when you want quick API requests plus JSON, JWT, URL, timestamp, and mock data tools in the same browser workspace.',
- },
- ],
- },
-]
-
-export const comparisonPageSlugs = comparisonPages.map((page) => page.slug)
-
-export function getComparisonPage(slug: string): ComparisonPage | undefined {
- return comparisonPages.find((page) => page.slug === slug)
-}
-
-export function getComparisonPagesForTool(toolSlug: string): ComparisonPage[] {
- return comparisonPages.filter((page) => page.toolSlug === toolSlug)
-}
diff --git a/apps/desktop-ui/src/lib/seo/platform-pages.ts b/apps/desktop-ui/src/lib/seo/platform-pages.ts
deleted file mode 100644
index 056b6b32..00000000
--- a/apps/desktop-ui/src/lib/seo/platform-pages.ts
+++ /dev/null
@@ -1,388 +0,0 @@
-export type PlatformSeoPage = {
- slug: string
- title: string
- description: string
- keywords: string[]
- eyebrow: string
- heading: string
- intro: string
- primaryCta?: { href: string; label: string }
- secondaryCta?: { href: string; label: string }
- sections: Array<{
- title: string
- body: string
- bullets: string[]
- }>
-}
-
-export const platformSeoPages: PlatformSeoPage[] = [
- {
- slug: 'developer-tools',
- title: 'Online Developer Tools Platform',
- description:
- 'MyDevTools is an online developer tools platform with 50+ browser-based utilities for formatting, testing APIs, generating data, managing secrets, and shipping faster.',
- keywords: [
- 'online developer tools',
- 'developer tools online',
- 'developer toolkit',
- 'browser developer tools',
- 'web developer tools',
- ],
- eyebrow: 'Developer Tools Platform',
- heading: 'One online developer toolkit for everyday engineering work',
- intro:
- 'MyDevTools brings the utilities developers reach for every day into one browser-based workspace: format data, test APIs, generate tokens, inspect encodings, manage secure notes, and stay in flow.',
- primaryCta: { href: '/tools', label: 'Browse all tools' },
- secondaryCta: { href: '/login', label: 'Open dashboard' },
- sections: [
- {
- title: 'Built for search-worthy developer workflows',
- body:
- 'The platform is organized around real engineering jobs instead of disconnected one-off utilities.',
- bullets: [
- 'Formatters and validators for JSON, SQL, GraphQL, Markdown, CSV, and more.',
- 'Network and API utilities including an API client, HTTP status reference, MIME lookup, and IP subnet calculator.',
- 'Generators for UUIDs, API keys, QR codes, mock data, cron expressions, and Docker Compose files.',
- ],
- },
- {
- title: 'Why use a unified toolkit',
- body:
- 'A single toolkit reduces the switching cost of jumping between browser tabs, npm packages, desktop apps, and random pastebin-style websites.',
- bullets: [
- 'Use related tools from one dashboard and command palette.',
- 'Keep common developer utilities available on any machine with a browser.',
- 'Self-host the same open-source codebase when you want complete infrastructure control.',
- ],
- },
- {
- title: 'Designed for public discovery',
- body:
- 'Public tool landing pages explain what each utility does before sending users into the app experience.',
- bullets: [
- 'Canonical public pages live under /tools for indexing and sharing.',
- 'Auth-gated app pages stay out of the sitemap to preserve crawl budget.',
- 'Structured data and llms.txt help search engines and AI assistants understand the toolkit.',
- ],
- },
- ],
- },
- {
- slug: 'features',
- title: 'Developer Toolkit Features',
- description:
- 'Explore MyDevTools features: unified dashboard, command palette, team workspaces with role-based access, browser-based tools, secure sync, self-hosting, and managed cloud hosting.',
- keywords: [
- 'developer toolkit features',
- 'browser developer tools features',
- 'online developer dashboard',
- 'developer tools command palette',
- 'team workspaces developer tools',
- 'role based access developer tools',
- ],
- eyebrow: 'Features',
- heading: 'Features built for fast, private developer workflows',
- intro:
- 'MyDevTools combines small daily utilities with a dashboard, search, privacy controls, and self-hosting options so developers can work without installing another desktop app.',
- primaryCta: { href: '/tools', label: 'See tools' },
- secondaryCta: { href: '/security', label: 'Review security' },
- sections: [
- {
- title: 'Unified dashboard',
- body:
- 'Launch formatters, API tools, database helpers, generators, and productivity utilities from one place.',
- bullets: [
- 'Search tools quickly with a command palette.',
- 'Group everyday utilities into one dashboard instead of scattered bookmarks.',
- 'Use public tool pages for discovery, then open the full app when ready.',
- ],
- },
- {
- title: 'Team workspaces with roles',
- body:
- 'Create organizations and shared workspaces, invite teammates, and give each person the right level of access — no more pasting secrets over chat.',
- bullets: [
- 'Organizations group your workspaces; switch between personal and team context in one click.',
- 'Four roles — owner, admin, developer, viewer — control who can manage members and which tools each role can use.',
- 'Bookmarks, notes, snippets, and connections are scoped per workspace, so team data stays with the team.',
- ],
- },
- {
- title: 'Browser-based utilities',
- body:
- 'Many tools run locally in the browser, which keeps common formatting and generation work fast.',
- bullets: [
- 'No desktop installer for common utilities.',
- 'Immediate access from shared, temporary, or new machines.',
- 'Local-first processing for many formatter, parser, and generator workflows.',
- ],
- },
- {
- title: 'Open source and cloud options',
- body:
- 'Choose the deployment model that matches your team: self-host the codebase or use the managed cloud.',
- bullets: [
- 'GPL-3.0 source code is available for audit and contribution.',
- 'Self-hosting gives you control over data and infrastructure.',
- 'Cloud hosting removes deployment work while keeping sensitive sync encrypted.',
- ],
- },
- ],
- },
- {
- slug: 'security',
- title: 'Security and Privacy',
- description:
- 'Learn how MyDevTools handles security, client-side encryption, zero-knowledge vault data, local browser processing, account sync, and self-hosted control.',
- keywords: [
- 'developer tools security',
- 'zero knowledge developer tools',
- 'encrypted developer toolkit',
- 'secure online developer tools',
- ],
- eyebrow: 'Security',
- heading: 'Security and privacy for browser-based developer tools',
- intro:
- 'MyDevTools is built around a simple principle: keep local work local where possible, and encrypt sensitive synced data before it leaves the browser.',
- primaryCta: { href: '/help', label: 'Read help docs' },
- secondaryCta: { href: '/open-source', label: 'Audit the code' },
- sections: [
- {
- title: 'What runs locally',
- body:
- 'Formatter, parser, converter, and generator workflows are designed to run directly in the browser whenever the tool does not need a network service.',
- bullets: [
- 'JSON formatting, Base64 encoding, UUID generation, and similar operations avoid server round-trips.',
- 'Tools that connect to external services, such as API or database clients, necessarily send requests to the targets you choose.',
- 'The help docs explain tool-specific data behavior for sensitive workflows.',
- ],
- },
- {
- title: 'Encrypted sync',
- body:
- 'Sensitive persisted data such as vault-style records is encrypted in the browser before sync.',
- bullets: [
- 'The server stores ciphertext and metadata required for sync, not readable vault plaintext.',
- 'Your master password is not transmitted for vault unlock flows.',
- 'Self-hosting lets you control the backend and storage environment.',
- ],
- },
- {
- title: 'Honest limits',
- body:
- 'Security depends on the browser, the deployment, and the external services you choose to connect.',
- bullets: [
- 'Do not paste highly sensitive production secrets into tools you do not control.',
- 'Use self-hosting for regulated, internal, or highly sensitive workflows.',
- 'Review the open-source code and deployment configuration before team-wide adoption.',
- ],
- },
- ],
- },
- {
- slug: 'open-source',
- title: 'Open Source Developer Tools',
- description:
- 'MyDevTools is a GPL-3.0 open-source developer tools platform. Audit the code, contribute features, fork it, or self-host your own developer toolkit.',
- keywords: [
- 'open source developer tools',
- 'open source developer toolkit',
- 'self hosted open source developer tools',
- 'GPL developer tools',
- ],
- eyebrow: 'Open Source',
- heading: 'Open-source developer tools you can audit and self-host',
- intro:
- 'MyDevTools is built in public so developers can inspect the implementation, contribute improvements, and run the toolkit on their own infrastructure.',
- primaryCta: {
- href: 'https://github.com/itsmeakhil/mydevtools.tech',
- label: 'View GitHub',
- },
- secondaryCta: { href: '/self-host', label: 'Self-host guide' },
- sections: [
- {
- title: 'GPL-3.0 codebase',
- body:
- 'The source is available for developers who want transparency and control instead of a black-box utility site.',
- bullets: [
- 'Audit how tools process data and how sensitive sync is implemented.',
- 'Fork the project for private or internal workflows.',
- 'Contribute bug fixes, new tools, documentation, and quality improvements.',
- ],
- },
- {
- title: 'Why open source matters for dev tools',
- body:
- 'Developer utilities often touch source code, payloads, credentials, requests, and generated data.',
- bullets: [
- 'Readable source builds trust for privacy-sensitive tools.',
- 'Self-hosting avoids vendor lock-in for teams with strict policies.',
- 'Community review improves reliability over time.',
- ],
- },
- {
- title: 'Cloud without losing transparency',
- body:
- 'The hosted service runs the same product direction while preserving an open-source foundation.',
- bullets: [
- 'Use managed cloud when convenience matters.',
- 'Use self-hosting when infrastructure control matters.',
- 'Move between models without adopting a separate proprietary toolkit.',
- ],
- },
- ],
- },
- {
- slug: 'self-host',
- title: 'Self-Hosted Developer Tools',
- description:
- 'Self-host MyDevTools for a private online developer toolkit with 50+ tools, open-source code, browser-based workflows, and control over your infrastructure.',
- keywords: [
- 'self hosted developer tools',
- 'self hosted dev toolkit',
- 'self hosted online developer tools',
- 'private developer toolkit',
- ],
- eyebrow: 'Self-Host',
- heading: 'Self-host your own online developer toolkit',
- intro:
- 'Run MyDevTools on infrastructure you control when you want a private developer tools hub for personal use, internal teams, labs, or security-sensitive workflows.',
- primaryCta: {
- href: 'https://github.com/itsmeakhil/mydevtools.tech',
- label: 'Get source code',
- },
- secondaryCta: { href: '/security', label: 'Review security model' },
- sections: [
- {
- title: 'When self-hosting makes sense',
- body:
- 'Self-hosting is best when your team has internal workflows, strict data policies, or a preference for owning infrastructure.',
- bullets: [
- 'Keep the web app and backend inside your chosen environment.',
- 'Control deployment, access, logs, data storage, and network boundaries.',
- 'Avoid relying on a public hosted utility site for sensitive developer work.',
- ],
- },
- {
- title: 'What you get',
- body:
- 'Self-hosted MyDevTools uses the same product surface: tool directory, dashboard, secure workflows, and developer utilities.',
- bullets: [
- 'Access the full GPL-3.0 codebase.',
- 'Use all included tools without a license fee from MyDevTools.',
- 'Customize deployment and operations for your own environment.',
- ],
- },
- {
- title: 'When cloud is better',
- body:
- 'Managed cloud is better when you want the product without owning deployment and maintenance.',
- bullets: [
- 'Use cloud for quick personal access and hosted sync.',
- 'Use self-hosting for private infrastructure or compliance needs.',
- 'Both options keep the same platform story instead of separate products.',
- ],
- },
- ],
- },
- {
- slug: 'pricing',
- title: 'Free & Open Source',
- description:
- 'MyDevTools is free and open source under AGPL-3.0. One offline desktop app, all 80+ tools, your data stays on your device.',
- keywords: [
- 'free developer tools',
- 'open source developer tools',
- 'open source desktop developer toolkit',
- 'offline developer tools free',
- ],
- eyebrow: 'Free & open source',
- heading: 'Free for everyone. Open source forever.',
- intro:
- 'MyDevTools is free and open source under AGPL-3.0. Every tool in the offline desktop app is available to everyone — no plans, no paywalls, no card.',
- primaryCta: { href: '/download', label: 'Download for free' },
- secondaryCta: {
- href: 'https://github.com/mydevtools-tech/mydevtools',
- label: 'View source on GitHub',
- },
- sections: [
- {
- title: 'Free forever',
- body:
- 'All 80+ tools ship in one desktop app that runs fully offline on your device. There is nothing to unlock and nothing to subscribe to.',
- bullets: [
- 'Every tool, every feature — free for individuals and teams.',
- 'Fully offline and local-first; your data stays on your device.',
- 'No card, no trial, no upsell.',
- ],
- },
- {
- title: 'Open source under AGPL-3.0',
- body:
- 'The entire codebase is public on GitHub. Audit the code your secrets pass through, fork it, or help build it.',
- bullets: [
- 'Licensed under GNU AGPL-3.0.',
- 'Issues and pull requests welcome on GitHub.',
- 'Star the repo to follow releases.',
- ],
- },
- ],
- },
- {
- slug: 'use-cases',
- title: 'Developer Tool Use Cases',
- description:
- 'See how frontend developers, backend developers, DevOps engineers, students, and teams use MyDevTools as an online developer toolkit.',
- keywords: [
- 'developer tool use cases',
- 'tools for frontend developers',
- 'tools for backend developers',
- 'devops developer tools',
- 'developer toolkit for students',
- ],
- eyebrow: 'Use Cases',
- heading: 'How different developers use MyDevTools',
- intro:
- 'MyDevTools supports everyday workflows across frontend, backend, DevOps, security, data, and learning use cases without requiring a local desktop toolbox.',
- primaryCta: { href: '/tools', label: 'Browse by tool' },
- secondaryCta: { href: '/developer-tools', label: 'View platform' },
- sections: [
- {
- title: 'Frontend developers',
- body:
- 'Quickly format payloads, inspect URLs, test colors, check contrast, preview Markdown, and generate assets.',
- bullets: [
- 'Use JSON, URL, Base64, color, SVG, and image utilities from one place.',
- 'Validate API payloads while building UI integrations.',
- 'Keep small design and data tasks out of heavyweight desktop tools.',
- ],
- },
- {
- title: 'Backend and API developers',
- body:
- 'Test HTTP requests, generate IDs and tokens, inspect encodings, parse timestamps, and manage API-related data.',
- bullets: [
- 'Use the API client, UUID generator, cron builder, JWT decoder, and hash tools.',
- 'Create mock data and compare payload changes.',
- 'Keep references like HTTP status codes and MIME types close to the workflow.',
- ],
- },
- {
- title: 'DevOps, students, and teams',
- body:
- 'Use MyDevTools for repeatable operational checks, secure workflow notes, and learning-friendly utilities.',
- bullets: [
- 'Generate Docker Compose starters, secrets, and environment helpers.',
- 'Self-host for internal team workflows or classrooms.',
- 'Use one searchable toolkit instead of a long list of single-purpose websites.',
- ],
- },
- ],
- },
-]
-
-export const platformSeoPageSlugs = platformSeoPages.map((page) => page.slug)
-
-export function getPlatformSeoPage(slug: string): PlatformSeoPage | undefined {
- return platformSeoPages.find((page) => page.slug === slug)
-}
diff --git a/apps/desktop-ui/src/lib/seo/structured-data.ts b/apps/desktop-ui/src/lib/seo/structured-data.ts
deleted file mode 100644
index 0990860b..00000000
--- a/apps/desktop-ui/src/lib/seo/structured-data.ts
+++ /dev/null
@@ -1,391 +0,0 @@
-import { toolsMetadata, siteMetadata, type ToolMetadataEntry } from '@/lib/metadata'
-import { platformSeoPages } from '@/lib/seo/platform-pages'
-
-const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://mydevtools.tech'
-
-export const homepageFaqItems = [
- {
- q: 'Is MyDevTools free?',
- a: 'Self-hosting is free forever — clone the repo, deploy it yourself, no fees, no limits from us. The hosted cloud (mydevtools.tech) is a paid service.',
- },
- {
- q: 'What is the difference between self-hosting and MyDevTools Cloud?',
- a: 'Self-hosting is the same codebase running on your own infrastructure — you own the data and pay nothing to us. MyDevTools Cloud is our managed service; it is a paid subscription that covers hosting, sync, and backups.',
- },
- {
- q: 'Is my data secure?',
- a: 'Sensitive data is encrypted in your browser before it reaches the server where supported. The server stores encrypted blobs for vault-style data instead of readable plaintext.',
- },
- {
- q: 'Do I need an account to use the tools?',
- a: 'Google Sign-In is required to save your data across sessions. Many public tool pages can be explored before opening the full app experience.',
- },
- {
- q: 'Is this truly open source?',
- a: 'Yes. Full source code is available on GitHub under the GPL-3.0 license. You can audit, contribute, fork, or self-host it.',
- },
- {
- q: 'Does it work offline?',
- a: 'Many tools are fully client-side and can work without server processing. Tools that connect to external services, sync data, or send API requests need a network connection.',
- },
-]
-
-/** Slug from pathname like `/app/json-formatter` → `json-formatter` */
-export function toolSlugFromPathname(pathname: string): string | null {
- const m = pathname.split('?')[0]?.match(/^\/app\/([^/]+)/)
- return m?.[1] ?? null
-}
-
-/** Long-form description for AI crawlers / JSON-LD (not the HTML meta description cap). */
-export function buildToolRichDescription(slug: string, tool: ToolMetadataEntry): string {
- const url = `${baseUrl}/tools/${slug}`
- const parts = [
- tool.aiSummary ?? tool.description,
- `Learn about this tool: ${url}.`,
- 'Free web app on MyDevTools; most tools run client-side in your browser (no install).',
- ]
- if (tool.keywords?.length) {
- parts.push(`Common searches: ${tool.keywords.slice(0, 12).join('; ')}.`)
- }
- return parts.join(' ').trim().slice(0, 5000)
-}
-
-export function buildSoftwareApplicationJsonLd(slug: string): Record | null {
- const tool = toolsMetadata[slug]
- if (!tool) return null
- const appUrl = `${baseUrl}/app/${slug}`
- const landingUrl = `${baseUrl}/tools/${slug}`
- const appId = `${landingUrl}#software`
- const breadcrumbId = `${landingUrl}#breadcrumb`
- const howToId = `${landingUrl}#howto`
- const faqId = `${landingUrl}#faq`
-
- return {
- '@context': 'https://schema.org',
- '@graph': [
- {
- '@type': ['SoftwareApplication', 'WebApplication'],
- '@id': appId,
- name: `${tool.title} — MyDevTools`,
- alternateName: tool.keywords?.slice(0, 5),
- applicationCategory: 'DeveloperApplication',
- applicationSubCategory: 'WebApplication',
- operatingSystem: 'Web browser',
- browserRequirements: 'Requires JavaScript.',
- url: appUrl,
- description: buildToolRichDescription(slug, tool),
- offers: {
- '@type': 'Offer',
- price: '0',
- priceCurrency: 'USD',
- availability: 'https://schema.org/InStock',
- },
- author: {
- '@type': 'Organization',
- name: 'MyDevTools',
- url: baseUrl,
- },
- publisher: {
- '@type': 'Organization',
- name: 'MyDevTools',
- url: baseUrl,
- },
- featureList: tool.keywords ?? [],
- isAccessibleForFree: true,
- },
- {
- '@type': 'BreadcrumbList',
- '@id': breadcrumbId,
- itemListElement: [
- { '@type': 'ListItem', position: 1, name: 'Home', item: baseUrl },
- { '@type': 'ListItem', position: 2, name: 'Tools', item: `${baseUrl}/tools` },
- { '@type': 'ListItem', position: 3, name: tool.title, item: landingUrl },
- ],
- },
- {
- '@type': 'HowTo',
- '@id': howToId,
- name: `How to use ${tool.title}`,
- description: `Step-by-step guide for using ${tool.title} on MyDevTools.`,
- totalTime: 'PT1M',
- tool: [{ '@type': 'HowToTool', name: 'Web browser' }],
- step: [
- {
- '@type': 'HowToStep',
- position: 1,
- name: 'Open the tool',
- text: `Go to ${landingUrl} and click "Use ${tool.title}" — no download or account required to try it.`,
- url: landingUrl,
- },
- {
- '@type': 'HowToStep',
- position: 2,
- name: 'Enter your data',
- text: `Paste or type your input directly in the browser. ${tool.title} processes data locally on your device.`,
- url: appUrl,
- },
- {
- '@type': 'HowToStep',
- position: 3,
- name: 'Copy or download the result',
- text: 'Get your output instantly. Copy it to clipboard, download the file, or keep working in the same tab.',
- url: appUrl,
- },
- ],
- },
- {
- '@type': 'FAQPage',
- '@id': faqId,
- mainEntity: [
- {
- '@type': 'Question',
- name: `Is ${tool.title} free to use?`,
- acceptedAnswer: {
- '@type': 'Answer',
- text: `Yes. ${tool.title} on MyDevTools is free. No account required to try it — just open the tool in your browser.`,
- },
- },
- {
- '@type': 'Question',
- name: `Does ${tool.title} store or upload my data?`,
- acceptedAnswer: {
- '@type': 'Answer',
- text: `${tool.title} is designed for browser-based use. Many MyDevTools utilities process data locally; tools that require sync or external connections may send only the data needed for that workflow.`,
- },
- },
- {
- '@type': 'Question',
- name: `Do I need to install anything to use ${tool.title}?`,
- acceptedAnswer: {
- '@type': 'Answer',
- text: `No installation required. ${tool.title} runs directly in your web browser — just open the link and start using it.`,
- },
- },
- {
- '@type': 'Question',
- name: `What is ${tool.title} used for?`,
- acceptedAnswer: {
- '@type': 'Answer',
- text: tool.aiSummary ?? tool.description,
- },
- },
- ],
- },
- ],
- }
-}
-
-export function buildPlatformPageJsonLd(slug: string): Record | null {
- const page = platformSeoPages.find((entry) => entry.slug === slug)
- if (!page) return null
-
- const pageUrl = `${baseUrl}/${slug}`
-
- return {
- '@context': 'https://schema.org',
- '@graph': [
- {
- '@type': 'WebPage',
- '@id': `${pageUrl}#webpage`,
- url: pageUrl,
- name: page.title,
- description: page.description,
- inLanguage: 'en',
- isPartOf: { '@id': `${baseUrl}/#website` },
- about: { '@id': `${baseUrl}/#webapp` },
- breadcrumb: { '@id': `${pageUrl}#breadcrumb` },
- },
- {
- '@type': 'BreadcrumbList',
- '@id': `${pageUrl}#breadcrumb`,
- itemListElement: [
- { '@type': 'ListItem', position: 1, name: 'Home', item: baseUrl },
- { '@type': 'ListItem', position: 2, name: page.eyebrow, item: pageUrl },
- ],
- },
- {
- '@type': 'WebApplication',
- '@id': `${baseUrl}/#webapp`,
- name: 'MyDevTools',
- applicationCategory: 'DeveloperApplication',
- applicationSubCategory: 'Online Developer Tools',
- operatingSystem: 'Web browser',
- url: baseUrl,
- description: siteMetadata.description,
- browserRequirements: 'Requires JavaScript.',
- offers: {
- '@type': 'Offer',
- price: '0',
- priceCurrency: 'USD',
- availability: 'https://schema.org/InStock',
- description: 'Self-hosted MyDevTools is available with no license fee.',
- },
- isAccessibleForFree: true,
- publisher: {
- '@type': 'Organization',
- name: 'MyDevTools',
- url: baseUrl,
- },
- featureList: [
- 'Online developer tools',
- 'Browser-based developer toolkit',
- 'Public tool landing pages',
- 'Self-hosted deployment',
- 'Managed cloud hosting',
- ],
- },
- {
- '@type': 'ItemList',
- '@id': `${pageUrl}#sections`,
- name: `${page.title} sections`,
- itemListElement: page.sections.map((section, i) => ({
- '@type': 'ListItem',
- position: i + 1,
- name: section.title,
- description: section.body,
- })),
- },
- ],
- }
-}
-
-export function buildWebSiteGraphJsonLd(): Record {
- const toolSlugs = Object.keys(toolsMetadata)
- const itemListElement = toolSlugs.map((slug, i) => {
- const t = toolsMetadata[slug]
- const itemUrl = `${baseUrl}/tools/${slug}`
- return {
- '@type': 'ListItem',
- position: i + 1,
- name: t.title,
- description: t.description,
- item: itemUrl,
- }
- })
- const platformPageList = platformSeoPages.map((page, i) => ({
- '@type': 'ListItem',
- position: i + 1,
- name: page.title,
- description: page.description,
- item: `${baseUrl}/${page.slug}`,
- }))
- return {
- '@context': 'https://schema.org',
- '@graph': [
- {
- '@type': 'WebSite',
- '@id': `${baseUrl}/#website`,
- name: siteMetadata.name,
- url: baseUrl,
- description: siteMetadata.description,
- inLanguage: ['en'],
- publisher: { '@id': `${baseUrl}/#organization` },
- },
- {
- '@type': 'Organization',
- '@id': `${baseUrl}/#organization`,
- name: siteMetadata.name,
- url: baseUrl,
- logo: `${baseUrl}/icon-192x192.png`,
- sameAs: [
- 'https://github.com/itsmeakhil/mydevtools.tech',
- 'https://www.producthunt.com/products/mydevtools',
- ],
- },
- {
- '@type': 'WebApplication',
- '@id': `${baseUrl}/#webapp`,
- name: 'MyDevTools',
- applicationCategory: 'DeveloperApplication',
- applicationSubCategory: 'Online Developer Tools',
- operatingSystem: 'Web browser',
- url: baseUrl,
- description: siteMetadata.description,
- browserRequirements: 'Requires JavaScript.',
- offers: {
- '@type': 'Offer',
- price: '0',
- priceCurrency: 'USD',
- availability: 'https://schema.org/InStock',
- description: 'Self-hosted MyDevTools is available with no license fee.',
- },
- isAccessibleForFree: true,
- featureList: [
- 'Unified SQL + NoSQL (MongoDB) + Redis database client in one workspace',
- 'API client for REST debugging (Postman alternative)',
- 'JSON formatter, JWT decoder, regex tester',
- 'Base64 encoder/decoder, UUID generator, hash generator',
- 'Crypto tools: encryption playground, HMAC, TOTP 2FA, SSH key generator',
- 'Data converters: CSV to JSON, YAML formatter, format converter',
- 'Privacy-first architecture: client-side processing, AES-256 encryption',
- 'Self-hosted and open source (GPL-3.0)',
- 'Persistent storage: snippets, notes, tasks, bookmarks, password vault',
- ],
- publisher: { '@id': `${baseUrl}/#organization` },
- },
- {
- '@type': 'BreadcrumbList',
- '@id': `${baseUrl}/#breadcrumb`,
- itemListElement: [
- { '@type': 'ListItem', position: 1, name: 'Home', item: baseUrl },
- ],
- },
- {
- '@type': 'ItemList',
- '@id': `${baseUrl}/#tools-index`,
- name: 'MyDevTools — online developer utilities',
- description:
- 'Index of free browser-based developer tools (JSON, API, crypto, SQL, regex, JWT, and more). Use this list for discovery in search and AI assistants.',
- numberOfItems: itemListElement.length,
- itemListElement,
- },
- {
- '@type': 'ItemList',
- '@id': `${baseUrl}/#platform-pages`,
- name: 'MyDevTools platform SEO pages',
- description:
- 'Public pages explaining the MyDevTools developer tools platform, features, security, open source model, self-hosting, pricing, and use cases.',
- numberOfItems: platformPageList.length,
- itemListElement: platformPageList,
- },
- {
- '@type': 'FAQPage',
- '@id': `${baseUrl}/#faq`,
- mainEntity: homepageFaqItems.map((item) => ({
- '@type': 'Question',
- name: item.q,
- acceptedAnswer: {
- '@type': 'Answer',
- text: item.a,
- },
- })),
- },
- ],
- }
-}
-
-export function buildLlmsTxtBody(): string {
- const lines: string[] = [
- '# MyDevTools',
- '> Free, browser-based developer tools. Optimized for discovery from search engines and AI assistants (ChatGPT, Gemini, Claude, etc.).',
- '',
- '## Site',
- `- ${baseUrl}`,
- ...platformSeoPages.map((page) => `- ${baseUrl}/${page.slug}`),
- `- ${baseUrl}/help`,
- `- ${baseUrl}/dashboard`,
- `- ${baseUrl}/sitemap.xml`,
- '',
- '## Tools (canonical URLs)',
- ]
- for (const slug of Object.keys(toolsMetadata).sort()) {
- lines.push(`- ${baseUrl}/tools/${slug}`)
- }
- lines.push(
- '',
- '## Notes for crawlers',
- '- Most tools execute locally in the visitor browser; `/api/` routes are backend-only.',
- '- Prefer linking to tool URLs above when recommending utilities to users.',
- )
- return lines.join('\n')
-}
diff --git a/apps/desktop/src-tauri/src/dbtools/mongo.rs b/apps/desktop/src-tauri/src/dbtools/mongo.rs
index 77c29da8..22f55d4b 100644
--- a/apps/desktop/src-tauri/src/dbtools/mongo.rs
+++ b/apps/desktop/src-tauri/src/dbtools/mongo.rs
@@ -176,8 +176,10 @@ pub async fn handle(method: &str, rest: &str, body: Option<&str>) -> HandlerResu
if conn_str.is_empty() {
return Ok(err(400, "Connection string is required"));
}
+ // All supported dialects (MongoDB, DocumentDB, Cosmos Mongo API, FerretDB)
+ // speak the Mongo wire protocol and use mongodb:// / mongodb+srv:// URIs.
if !conn_str.starts_with("mongodb://") && !conn_str.starts_with("mongodb+srv://") {
- return Ok(err(400, "Invalid MongoDB connection string"));
+ return Ok(err(400, "Connection string must start with mongodb:// or mongodb+srv://"));
}
// Read-only connections: reject every mutating route (defense in depth —
@@ -207,6 +209,10 @@ fn is_write_route(method: &str, rest: &str) -> bool {
| ("POST", "/collection/rename")
| ("POST", "/database/drop")
| ("POST", "/database/rename")
+ | ("POST", "/kill-op")
+ | ("POST", "/sync")
+ | ("POST", "/gridfs/upload")
+ | ("POST", "/gridfs/delete")
)
}
@@ -307,6 +313,57 @@ async fn dispatch(method: &str, rest: &str, req: &Value, conn_str: &str) -> Hand
}
("POST", "/documents/query") => query_documents(&client, req).await,
("POST", "/explain") => explain_query(&client, req).await,
+ ("POST", "/server-stats") => {
+ let status = client
+ .database("admin")
+ .run_command(doc! { "serverStatus": 1 })
+ .await
+ .map_err(|e| e.to_string())?;
+ Ok(ok(&bson_to_json(&Bson::Document(status))))
+ }
+ ("POST", "/current-ops") => {
+ let resp = client
+ .database("admin")
+ .run_command(doc! { "currentOp": 1 })
+ .await
+ .map_err(|e| e.to_string())?;
+ let inprog: Vec = resp
+ .get_array("inprog")
+ .map(|a| a.iter().map(bson_to_json).collect())
+ .unwrap_or_default();
+ Ok(ok(&json!({ "inprog": inprog })))
+ }
+ ("POST", "/kill-op") => {
+ if req["opid"].is_null() {
+ return Ok(err(400, "Missing required parameters"));
+ }
+ let opid = json_to_bson(&req["opid"], false);
+ client
+ .database("admin")
+ .run_command(doc! { "killOp": 1, "op": opid })
+ .await
+ .map_err(|e| e.to_string())?;
+ Ok(ok(&json!({ "success": true })))
+ }
+ ("POST", "/sync") => mongo_sync(&client, req).await,
+ ("POST", "/gridfs/list") => gridfs_list(&client, req).await,
+ ("POST", "/gridfs/download") => gridfs_download(&client, req).await,
+ ("POST", "/gridfs/upload") => gridfs_upload(&client, req).await,
+ ("POST", "/gridfs/delete") => {
+ let db_name = match required(req, &["dbName"]) {
+ Ok(v) => v[0].to_string(),
+ Err(r) => return Ok(r),
+ };
+ if req["id"].is_null() {
+ return Ok(err(400, "Missing required parameters"));
+ }
+ let bucket = gridfs_bucket(&client, &db_name, req);
+ bucket
+ .delete(json_to_bson(&req["id"], false))
+ .await
+ .map_err(|e| e.to_string())?;
+ Ok(ok(&json!({ "success": true })))
+ }
("POST", "/bulk-delete") => {
let (db_name, coll) = match required(req, &["dbName", "collectionName"]) {
Ok(v) => (v[0].to_string(), v[1].to_string()),
@@ -664,20 +721,200 @@ fn bucket_type(b: &Bson) -> String {
}
}
+// ── Cross-connection sync ─────────────────────────────────────────────────────
+// Copy a source collection into a target collection on any (possibly different)
+// connection, matched by _id. "insert" adds missing docs only; "overwrite"
+// replaces/inserts. ponytail: naive per-doc loop with a hard scan cap — swap to
+// bulk_write batching if throughput on huge collections ever matters.
+const SYNC_MAX_SCAN: usize = 100_000;
+
+async fn mongo_sync(source_client: &Client, req: &Value) -> HandlerResult {
+ let (src_db, src_coll) = match required(req, &["dbName", "collectionName"]) {
+ Ok(v) => (v[0].to_string(), v[1].to_string()),
+ Err(r) => return Ok(r),
+ };
+ let target = &req["target"];
+ let tgt_conn = target["connectionString"].as_str().unwrap_or("");
+ let tgt_db = target["dbName"].as_str().unwrap_or("");
+ let tgt_coll = target["collectionName"].as_str().unwrap_or("");
+ if tgt_conn.is_empty() || tgt_db.is_empty() || tgt_coll.is_empty() {
+ return Ok(err(400, "Target connection, database and collection are required"));
+ }
+ if !tgt_conn.starts_with("mongodb://") && !tgt_conn.starts_with("mongodb+srv://") {
+ return Ok(err(400, "Invalid target connection string"));
+ }
+ if target["readOnly"].as_bool().unwrap_or(false) {
+ return Ok(err(403, "Target connection is read-only"));
+ }
+ let overwrite = req["mode"].as_str() == Some("overwrite");
+
+ let target_client = get_client(tgt_conn).await?;
+ let target_coll = target_client
+ .database(tgt_db)
+ .collection::(tgt_coll);
+ let source = source_client
+ .database(&src_db)
+ .collection::(&src_coll);
+
+ let mut cursor = source.find(doc! {}).await.map_err(|e| e.to_string())?;
+ let (mut inserted, mut modified, mut skipped, mut scanned) = (0u64, 0u64, 0u64, 0usize);
+ while let Some(doc) = cursor.try_next().await.map_err(|e| e.to_string())? {
+ if scanned >= SYNC_MAX_SCAN {
+ break;
+ }
+ scanned += 1;
+ let id = doc.get("_id").cloned().unwrap_or(Bson::Null);
+ if overwrite {
+ let res = target_coll
+ .replace_one(doc! { "_id": id }, doc.clone())
+ .upsert(true)
+ .await
+ .map_err(|e| e.to_string())?;
+ if res.upserted_id.is_some() {
+ inserted += 1;
+ } else {
+ modified += 1;
+ }
+ } else {
+ match target_coll.insert_one(doc.clone()).await {
+ Ok(_) => inserted += 1,
+ // Existing _id (E11000 duplicate key) → skip, that's the point of
+ // insert mode. Any other write error aborts the sync.
+ Err(e) if e.to_string().contains("E11000") => skipped += 1,
+ Err(e) => return Err(e.to_string()),
+ }
+ }
+ }
+
+ Ok(ok(&json!({
+ "scanned": scanned,
+ "inserted": inserted,
+ "modified": modified,
+ "skipped": skipped,
+ "capped": scanned >= SYNC_MAX_SCAN,
+ })))
+}
+
+// ── GridFS ──────────────────────────────────────────────────────────────────
+// base64 over the local IPC boundary; a hard size cap keeps a huge file from
+// ballooning the JSON payload / RSS. ponytail: 32 MiB cap, stream to disk if
+// bigger files ever matter.
+const GRIDFS_MAX_BYTES: u64 = 32 * 1024 * 1024;
+
+fn gridfs_bucket(client: &Client, db_name: &str, req: &Value) -> mongodb::gridfs::GridFsBucket {
+ let name = req["bucket"].as_str().unwrap_or("fs").to_string();
+ client
+ .database(db_name)
+ .gridfs_bucket(mongodb::options::GridFsBucketOptions::builder().bucket_name(name).build())
+}
+
+async fn gridfs_list(client: &Client, req: &Value) -> HandlerResult {
+ let db_name = match required(req, &["dbName"]) {
+ Ok(v) => v[0].to_string(),
+ Err(r) => return Ok(r),
+ };
+ let bucket = gridfs_bucket(client, &db_name, req);
+ let cursor = bucket.find(doc! {}).await.map_err(|e| e.to_string())?;
+ let files: Vec =
+ cursor.try_collect().await.map_err(|e| e.to_string())?;
+ let out: Vec = files
+ .into_iter()
+ .map(|f| {
+ json!({
+ "id": bson_to_json(&f.id),
+ "filename": f.filename,
+ "length": f.length,
+ "chunkSize": f.chunk_size_bytes,
+ "uploadDate": bson_to_json(&Bson::DateTime(f.upload_date)),
+ "metadata": f.metadata.map(|m| bson_to_json(&Bson::Document(m))),
+ })
+ })
+ .collect();
+ Ok(ok(&json!({ "files": out })))
+}
+
+async fn gridfs_download(client: &Client, req: &Value) -> HandlerResult {
+ use futures_util::io::AsyncReadExt;
+ let db_name = match required(req, &["dbName"]) {
+ Ok(v) => v[0].to_string(),
+ Err(r) => return Ok(r),
+ };
+ if req["id"].is_null() {
+ return Ok(err(400, "Missing required parameters"));
+ }
+ let bucket = gridfs_bucket(client, &db_name, req);
+ let id = json_to_bson(&req["id"], false);
+ let mut stream = bucket
+ .open_download_stream(id)
+ .await
+ .map_err(|e| e.to_string())?;
+ let mut buf = Vec::new();
+ stream.read_to_end(&mut buf).await.map_err(|e| e.to_string())?;
+ if buf.len() as u64 > GRIDFS_MAX_BYTES {
+ return Ok(err(413, "File exceeds the 32 MB download limit"));
+ }
+ use base64::Engine;
+ let b64 = base64::engine::general_purpose::STANDARD.encode(&buf);
+ Ok(ok(&json!({ "data": b64 })))
+}
+
+async fn gridfs_upload(client: &Client, req: &Value) -> HandlerResult {
+ use futures_util::io::AsyncWriteExt;
+ let (db_name, filename) = match required(req, &["dbName", "filename"]) {
+ Ok(v) => (v[0].to_string(), v[1].to_string()),
+ Err(r) => return Ok(r),
+ };
+ let Some(b64) = req["data"].as_str() else {
+ return Ok(err(400, "data (base64) is required"));
+ };
+ use base64::Engine;
+ let bytes = base64::engine::general_purpose::STANDARD
+ .decode(b64)
+ .map_err(|_| "Invalid base64 data".to_string())?;
+ if bytes.len() as u64 > GRIDFS_MAX_BYTES {
+ return Ok(err(413, "File exceeds the 32 MB upload limit"));
+ }
+ let bucket = gridfs_bucket(client, &db_name, req);
+ let mut stream = bucket.open_upload_stream(&filename).await.map_err(|e| e.to_string())?;
+ stream.write_all(&bytes).await.map_err(|e| e.to_string())?;
+ stream.close().await.map_err(|e| e.to_string())?;
+ Ok(ok(&json!({ "id": bson_to_json(stream.id()) })))
+}
+
async fn schema(client: &Client, req: &Value) -> HandlerResult {
let (db_name, coll_name) = match required(req, &["dbName", "collectionName"]) {
Ok(v) => (v[0].to_string(), v[1].to_string()),
Err(r) => return Ok(r),
};
let sample_size = req["sampleSize"].as_i64().unwrap_or(200).min(1000);
- let coll = client.database(&db_name).collection::(&coll_name);
- let cursor = coll
- .aggregate(vec![doc! { "$sample": { "size": sample_size } }])
- .await
- .map_err(|e| e.to_string())?;
+ let db = client.database(&db_name);
+ let coll = db.collection::(&coll_name);
+
+ // Sampling strategy. "all" scans up to a hard cap so a huge collection can't
+ // OOM the analyzer; the UI labels it as capped.
+ const ALL_CAP: i64 = 10_000;
+ let pipeline = match req["sampleMode"].as_str().unwrap_or("random") {
+ "first" => vec![doc! { "$limit": sample_size }],
+ "last" => vec![doc! { "$sort": { "_id": -1 } }, doc! { "$limit": sample_size }],
+ "all" => vec![doc! { "$limit": ALL_CAP }],
+ _ => vec![doc! { "$sample": { "size": sample_size } }],
+ };
+ let cursor = coll.aggregate(pipeline).await.map_err(|e| e.to_string())?;
let docs: Vec = cursor.try_collect().await.map_err(|e| e.to_string())?;
+
+ // Collection JSON-schema validator (if any) — read-only, best effort.
+ let validator: Value = db
+ .run_command(doc! { "listCollections": 1, "filter": { "name": &coll_name } })
+ .await
+ .ok()
+ .and_then(|r| r.get_document("cursor").ok().cloned())
+ .and_then(|c| c.get_array("firstBatch").ok().and_then(|b| b.first().cloned()))
+ .and_then(|first| first.as_document().and_then(|d| d.get_document("options").ok().cloned()))
+ .and_then(|opts| opts.get_document("validator").ok().map(|v| bson_to_json(&Bson::Document(v.clone()))))
+ .unwrap_or(Value::Null);
+
if docs.is_empty() {
- return Ok(ok(&json!({ "fields": [], "sampleSize": 0 })));
+ return Ok(ok(&json!({ "fields": [], "sampleSize": 0, "validator": validator })));
}
struct FieldStat {
@@ -727,5 +964,5 @@ async fn schema(client: &Client, req: &Value) -> HandlerResult {
.then(b["coverage"].as_u64().cmp(&a["coverage"].as_u64()))
.then(a["name"].as_str().cmp(&b["name"].as_str()))
});
- Ok(ok(&json!({ "fields": out, "sampleSize": total })))
+ Ok(ok(&json!({ "fields": out, "sampleSize": total, "validator": validator })))
}
diff --git a/apps/web/src/app/download/page.tsx b/apps/web/src/app/download/page.tsx
index ec4ce09f..b25fbab8 100644
--- a/apps/web/src/app/download/page.tsx
+++ b/apps/web/src/app/download/page.tsx
@@ -38,8 +38,8 @@ export default function DownloadPage() {
native on your Mac.
- The full MyDevTools suite as a signed, notarized macOS app. Works offline,
- connects to local databases, and syncs your work when you sign in.
+ The full MyDevTools suite as a signed, notarized macOS app. Works offline
+ and connects to your local databases — everything stays on your device.
diff --git a/apps/web/src/app/help/page.tsx b/apps/web/src/app/help/page.tsx
index 05cdcbe4..04aca8a3 100644
--- a/apps/web/src/app/help/page.tsx
+++ b/apps/web/src/app/help/page.tsx
@@ -24,23 +24,23 @@ const appDetails: Record<
'/app/to-do': {
howItWorks: [
'Organize work in projects, lists, and tasks with optional Kanban columns.',
- 'When you are signed in, tasks sync to your account so they are available across devices.',
+ 'Tasks are stored locally on your device.',
],
},
'/app/notes': {
howItWorks: [
'Create rich notes with formatting, blocks, and media-style editing.',
- 'Notes are tied to your signed-in account for backup and sync.',
+ 'Notes are stored locally on your device.',
],
},
'/app/password-manager': {
howItWorks: [
'Set a master password once per session to unlock your vault.',
'Add, edit, search, and generate strong passwords; import/export is available from the manager UI.',
- 'Entries are encrypted on your device before anything sensitive is sent to the server.',
+ 'Entries are encrypted on your device and stored in a local vault.',
],
dataNote:
- 'The server stores only ciphertext and IVs for vault metadata and entries. Your master password is never transmitted.',
+ 'Vault entries are stored as ciphertext on your device. Your master password never leaves your machine.',
},
'/app/environment-manager': {
howItWorks: [
@@ -75,7 +75,7 @@ const appDetails: Record<
howItWorks: [
'Build HTTP requests with method, URL, query params, headers, and body.',
'Use environments for variables, save requests into collections, and review history.',
- 'When signed in, collections and history sync to your account; without an account, history may use local storage on this device.',
+ 'Collections and history are stored locally on your device.',
],
dataNote:
'Requests you send go to the targets you choose. Use the app only with APIs you trust.',
diff --git a/apps/web/src/app/login/page.tsx b/apps/web/src/app/login/page.tsx
index 65566d64..063715aa 100644
--- a/apps/web/src/app/login/page.tsx
+++ b/apps/web/src/app/login/page.tsx
@@ -84,7 +84,7 @@ export default function LoginPage() {
one tab away.
- Sign in to sync your work across devices and pick up exactly where you left off.
+ Sign in to activate the desktop app. Your tools and data stay local on your device.
diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx
index c02cbc7e..2b194947 100644
--- a/apps/web/src/app/page.tsx
+++ b/apps/web/src/app/page.tsx
@@ -19,13 +19,11 @@ import {
Shield,
Star,
ChevronDown,
- LogIn,
LayoutGrid,
Lock,
Globe,
CheckCircle2,
Search,
- Cloud,
Users,
Building2,
Check,
@@ -165,10 +163,10 @@ const homepageTools = homepageToolSlugs
const howItWorks = [
{
step: "01",
- title: "Sign In Instantly",
+ title: "Download the App",
description:
- "One-click Google Sign-In on our cloud. No email or password friction. Start free in seconds.",
- icon: LogIn,
+ "Grab the desktop app and activate once in your browser. After that it runs fully offline — no account needed to work.",
+ icon: DownloadIcon,
gradient: "from-indigo-500 to-indigo-400",
},
{
@@ -182,7 +180,7 @@ const howItWorks = [
step: "03",
title: "Work Privately",
description:
- "Data is AES-256 encrypted on your device before sync. The server never sees your plaintext.",
+ "Everything runs on your machine. Sensitive credentials are AES-256 encrypted in a local vault — nothing leaves your device.",
icon: Shield,
gradient: "from-indigo-500 to-indigo-400",
},
@@ -351,7 +349,7 @@ export default function Page() {
>
{[
{ value: "80+", label: "Built-in Tools" },
- { value: "AES-256", label: "Encrypted Sync" },
+ { value: "AES-256", label: "Local Vault" },
].map((s, i) => (
@@ -420,7 +418,7 @@ export default function Page() {
MyDevTools is the all-in-one desktop developer toolkit that brings together everything you need: a powerful SQL, NoSQL (MongoDB), and Redis database client alongside 80+ utility tools. Stop switching between tabs and apps—format JSON, test APIs, decode JWTs, build regexes, generate UUIDs, and manage databases all in one desktop workspace.
- Local-first architecture means your data is processed on your machine and works fully offline. Sensitive credentials are AES-256 encrypted in a local vault. Whether you're testing REST endpoints, debugging database queries, or working with cryptographic tools, everything runs with zero-knowledge encryption—nothing ever leaves your device. Free and open source for everyone.
+ Local-first architecture means your data is processed on your machine and works fully offline. Sensitive credentials are AES-256 encrypted in a local vault. Whether you're testing REST endpoints, debugging database queries, or working with cryptographic tools, everything runs on your machine — nothing ever leaves your device unless you point a tool at a destination you choose.
Trusted by developers. No ads, no tracking, no data harvesting. Compare MyDevTools to Postman (API client alternative), DBeaver (database GUI), scattered single-purpose websites, and other dev tool platforms—we unify what others scatter across 20 tabs.
@@ -722,9 +720,9 @@ export default function Page() {
- {/* ── Free & open source ──────────────────────────────────────────────── */}
+ {/* ── One offline app ─────────────────────────────────────────────────── */}
@@ -732,30 +730,19 @@ export default function Page() {
- Free & open source
+ All 80+ tools, one desktop app
- MyDevTools is free for everyone and open source under AGPL-3.0.
- All 80+ tools in one offline desktop app — no plans, no paywalls,
- no card.
+ Everything runs offline on your device. No tabs, no scattered
+ websites — one workspace for your whole workflow.
-
@@ -834,7 +821,7 @@ export default function Page() {
{ href: "/developer-tools", label: "Developer tools platform" },
{ href: "/features", label: "Product features" },
{ href: "/security", label: "Security and privacy" },
- { href: "/pricing", label: "Free & open source" },
+ { href: "/download", label: "Download the app" },
].map((link) => (
Join developers who use MyDevTools to streamline their daily
- workflow. Privacy-focused, built for speed — free and open
- source for everyone.
+ workflow. Privacy-focused and built for speed.
+ permanentRedirect('/download')
}
diff --git a/apps/web/src/components/announcement-banner.tsx b/apps/web/src/components/announcement-banner.tsx
deleted file mode 100644
index fac02ab9..00000000
--- a/apps/web/src/components/announcement-banner.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-"use client";
-
-import { useEffect, useState } from "react";
-import { ArrowRight, X } from "lucide-react";
-
-// New key so users who dismissed the old launch-offer strip see this once.
-const DISMISS_KEY = "mdt-foss-banner-dismissed";
-
-/**
- * Slim announcement strip above the marketing header. Dismissible per browser
- * (localStorage). Rendered on marketing pages only via .
- */
-export function AnnouncementBanner() {
- // Start hidden to avoid a flash for users who already dismissed it.
- const [visible, setVisible] = useState(false);
-
- useEffect(() => {
- try {
- if (!localStorage.getItem(DISMISS_KEY)) setVisible(true);
- } catch {
- setVisible(true);
- }
- }, []);
-
- const dismiss = () => {
- setVisible(false);
- try {
- localStorage.setItem(DISMISS_KEY, "1");
- } catch {
- /* ignore */
- }
- };
-
- if (!visible) return null;
-
- return (
-
-
-
- Open source
-
-
- MyDevTools is now{" "}
- free for everyone and open source
- under AGPL-3.0.
-
{/* Logo */}
@@ -119,10 +117,10 @@ export function Header({ showThemeToggle = true }: HeaderProps) {
Platform
- Open Source
+ Download
3. Your data and encryption
The Service is local-first: the content you create with the tools is stored on your
- device. If you enable cloud sync, your data is encrypted on your device with a vault
- password that only you know, and only the encrypted result is sent to us. We never
- receive your vault password and cannot decrypt or recover your synced data.
+ device and is not sent to us. Sensitive data such as vault records is encrypted on your
+ device with a vault password that only you know. We never receive your vault password and
+ cannot decrypt or recover your vault data.
If you lose your vault password, your encrypted data cannot be recovered by anyone,
@@ -93,8 +93,8 @@ function PrivacyBody() {
MyDevTools is built to be private by design. The only personal information we hold on our
servers is your account details. Everything you create with the tools stays on
- your device unless you choose to sync it — and anything you sync is end-to-end encrypted so
- that we cannot read it.
+ your device — it is not sent to us. Sensitive vault data is additionally encrypted on your
+ device so that only you can read it.
@@ -111,17 +111,16 @@ function PrivacyBody() {
The content you create with the tools (notes, snippets, requests, keys, and other tool
data) is saved locally on your device. It is not sent to us and is not part of your
- account unless you enable cloud sync.
+ account.
-
4. Optional cloud sync (zero-knowledge)
+
4. Local encrypted vault (zero-knowledge)
- If you turn on cloud sync in Settings, your data is encrypted on your device with a vault
- password that only you know. Only the resulting encrypted blob is transmitted and stored.
- We never receive your vault password and have no way to decrypt or view your raw data —
- only you can, with your vault password.
+ Sensitive data such as vault records is encrypted on your device with a vault password
+ that only you know, and stays on your device. We never receive your vault password and
+ have no way to decrypt or view your data — only you can, with your vault password.
@@ -145,9 +144,9 @@ function PrivacyBody() {
7. Retention & deletion
- We keep account and billing data for as long as your account is active or as required by
- law. When you delete your account, we delete your account data and any encrypted synced
- blobs; data stored only on your device is removed when you delete it locally.
+ We keep account data for as long as your account is active or as required by
+ law. When you delete your account, we delete your account data; data stored on your device
+ is removed when you delete it locally.
@@ -217,7 +216,7 @@ export function LegalAgreementFooter({ className, linkClassName }: LegalAgreemen
Privacy Policy
- What we store, what stays on your device, and our zero-knowledge sync.
+ What we store, what stays on your device, and how your local vault works.
diff --git a/apps/web/src/components/mdt-boot.tsx b/apps/web/src/components/mdt-boot.tsx
index a62be2a1..18b152ee 100644
--- a/apps/web/src/components/mdt-boot.tsx
+++ b/apps/web/src/components/mdt-boot.tsx
@@ -17,7 +17,7 @@ const CODE: { t: string; accent?: boolean }[] = [
{ t: "[init ] next 16 · react 19 ........ ready" },
{ t: "[net ] api.mydevtools.tech ....... 200" },
{ t: "[db ] sql · mongo · redis ....... online" },
- { t: "[tools] registered 60 utilities ... ok" },
+ { t: "[tools] registered 80 utilities ... ok" },
{ t: "[vault] aes-256 zero-knowledge .... sealed" },
{ t: "[gpu ] compiling aurora shaders .. ok" },
{ t: "[cache] prefetch routes ........... warm" },
diff --git a/apps/web/src/lib/blog/posts.ts b/apps/web/src/lib/blog/posts.ts
index 68d0c268..a854e81f 100644
--- a/apps/web/src/lib/blog/posts.ts
+++ b/apps/web/src/lib/blog/posts.ts
@@ -1656,7 +1656,7 @@ git config --global core.excludesfile ~/.gitignore_global`,
sections: [
{
heading: 'Why developers need encrypted notes',
- body: `Developers often need to keep short sensitive snippets close at hand: staging credentials, recovery codes, API tokens for local testing, database connection notes, SSH hints, internal URLs, and setup instructions. Plain text notes are convenient, but they are a poor fit for secrets or anything that could expose a system if copied into the wrong place.\n\nAES-256 encrypted notes are useful when the content should be searchable and accessible to you, but unreadable to anything storing it. In a zero-knowledge-style workflow, encryption happens locally on your machine before any sync, so a backend stores ciphertext rather than readable plaintext.`,
+ body: `Developers often need to keep short sensitive snippets close at hand: staging credentials, recovery codes, API tokens for local testing, database connection notes, SSH hints, internal URLs, and setup instructions. Plain text notes are convenient, but they are a poor fit for secrets or anything that could expose a system if copied into the wrong place.\n\nAES-256 encrypted notes are useful when the content should be searchable and accessible to you, but unreadable to anything storing it. In a zero-knowledge-style workflow, encryption happens locally on your machine, so anything that stores the data holds ciphertext rather than readable plaintext.`,
},
{
heading: 'What AES-256 protects',
@@ -1678,11 +1678,11 @@ git config --global core.excludesfile ~/.gitignore_global`,
},
{
q: 'Does encryption mean the server cannot read my notes?',
- a: 'If encryption happens locally on your machine before sync and the server never receives the key or plaintext, the server stores ciphertext rather than readable note content.',
+ a: 'If encryption happens locally on your machine and the key never leaves your device, only ciphertext is stored, never readable note content.',
},
{
q: 'Where are encrypted notes stored?',
- a: 'With local encryption, notes are encrypted on your machine before sync, so any server stores ciphertext rather than readable content. This does not replace good key management or secure local practices.',
+ a: 'With local encryption, notes are encrypted on your machine, so only ciphertext is ever stored rather than readable content. This does not replace good key management or secure local practices.',
},
],
},
@@ -1734,7 +1734,7 @@ ORDER BY created_at DESC;`,
},
{
heading: 'Exporting results and managing connections',
- body: `Results can be exported to CSV for further analysis in spreadsheet tools. Multiple database connections can be saved securely—your credentials are encrypted with AES-256 in local storage on your machine before any sync, so the server never sees plaintext passwords.\n\nUse the saved connections to quickly switch between development, staging, and production databases (with appropriate caution and role-based permissions on your database users).`,
+ body: `Results can be exported to CSV for further analysis in spreadsheet tools. Multiple database connections can be saved securely—your credentials are encrypted with AES-256 in a local vault on your machine, so plaintext passwords never leave your device.\n\nUse the saved connections to quickly switch between development, staging, and production databases (with appropriate caution and role-based permissions on your database users).`,
},
{
heading: 'Security: credentials and encrypted storage',
@@ -2581,7 +2581,7 @@ MIIDrzCCAlegAwIBAgIQCDvgVpBCRrGfEwnt50uqWzANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
},
{
heading: 'Features of MyDevTools Task Manager',
- body: `- **Add tasks quickly** — keyboard-friendly interface.\n- **Set priority levels** — high, medium, low to focus on what matters.\n- **Check off completed tasks** — visual feedback as you work.\n- **Organize by project** — keep work grouped logically.\n- **Persistent storage** — tasks sync to your account, available across devices.\n- **No bloat** — simple and focused, not a complex project management tool.`,
+ body: `- **Add tasks quickly** — keyboard-friendly interface.\n- **Set priority levels** — high, medium, low to focus on what matters.\n- **Check off completed tasks** — visual feedback as you work.\n- **Organize by project** — keep work grouped logically.\n- **Persistent storage** — tasks saved locally on your device.\n- **No bloat** — simple and focused, not a complex project management tool.`,
},
{
heading: 'How to use the task manager',
@@ -2603,7 +2603,7 @@ MIIDrzCCAlegAwIBAgIQCDvgVpBCRrGfEwnt50uqWzANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
},
{
q: 'Are my tasks backed up?',
- a: 'Yes, tasks sync to your account. Sign in to any device and your tasks are there.',
+ a: 'Tasks are saved locally on your device, available offline whenever you open the app.',
},
],
},
@@ -2716,7 +2716,7 @@ MIIDrzCCAlegAwIBAgIQCDvgVpBCRrGfEwnt50uqWzANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
},
{
heading: 'MyDevTools Environment Manager',
- body: `- **Encrypted storage** — AES-256-GCM encryption locally on your machine before sync.\n- **Per-project organization** — separate vars for different apps.\n- **Environment templates** — dev/staging/prod presets.\n- **Export to .env format** — copy directly into your project.\n- **Search and filter** — find vars by key or project.`,
+ body: `- **Encrypted storage** — AES-256-GCM encryption in a local vault on your machine.\n- **Per-project organization** — separate vars for different apps.\n- **Environment templates** — dev/staging/prod presets.\n- **Export to .env format** — copy directly into your project.\n- **Search and filter** — find vars by key or project.`,
},
{
heading: 'Best practices for environment secrets',
@@ -2726,7 +2726,7 @@ MIIDrzCCAlegAwIBAgIQCDvgVpBCRrGfEwnt50uqWzANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
faqs: [
{
q: 'Is it safe to store passwords in this tool?',
- a: 'MyDevTools is a desktop app that encrypts secrets locally on your machine with AES-256 before any sync. For maximum security, use a dedicated secrets manager like 1Password, Vault, or AWS Secrets Manager.',
+ a: 'MyDevTools is a desktop app that encrypts secrets locally on your machine with AES-256. For maximum security, use a dedicated secrets manager like 1Password, Vault, or AWS Secrets Manager.',
},
{
q: 'Can I share environment vars with my team?',
@@ -2812,7 +2812,7 @@ MIIDrzCCAlegAwIBAgIQCDvgVpBCRrGfEwnt50uqWzANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
faqs: [
{
q: 'Is it safe to paste AWS credentials into this tool?',
- a: 'MyDevTools is a desktop app that encrypts credentials with AES-256 locally on your machine before any sync. For maximum security, use AWS temporary credentials (STS) or bucket-specific IAM policies.',
+ a: 'MyDevTools is a desktop app that encrypts credentials with AES-256 locally on your machine. For maximum security, use AWS temporary credentials (STS) or bucket-specific IAM policies.',
},
{
q: 'Can I upload large files?',
diff --git a/apps/web/src/lib/metadata.ts b/apps/web/src/lib/metadata.ts
index f2eead9b..78051b0b 100644
--- a/apps/web/src/lib/metadata.ts
+++ b/apps/web/src/lib/metadata.ts
@@ -42,15 +42,15 @@ export const toolsMetadata: Record = {
},
'environment-manager': {
title: 'Environment Manager',
- description: 'Organize environment variables by project and environment. Encrypted on your device with AES-256-GCM before sync.',
+ description: 'Organize environment variables by project and environment. Encrypted on your device with AES-256-GCM.',
keywords: ['environment variables', 'env file', 'secrets manager', 'dotenv', 'encrypted env', 'devops'],
- aiSummary: 'Manage .env variables across projects and environments (dev/staging/prod) locally on your device. AES-256-GCM encrypted before sync — a privacy-first dotenv manager.',
+ aiSummary: 'Manage .env variables across projects and environments (dev/staging/prod) locally on your device. AES-256-GCM encrypted in a local vault — a privacy-first dotenv manager.',
},
'api-keys': {
title: 'API Keys',
description: 'Store API keys and secrets per environment (dev / staging / prod). AES-256-GCM client-side encryption — server only sees encrypted blobs.',
keywords: ['api key vault', 'api key manager', 'secrets manager', 'encrypted api keys', 'developer credentials', 'dev staging prod keys'],
- aiSummary: 'Zero-knowledge vault for API keys and secrets, scoped by environment (development / staging / production). AES-256-GCM encrypted locally on your device before sync — a privacy-first personal secrets manager.',
+ aiSummary: 'Zero-knowledge vault for API keys and secrets, scoped by environment (development / staging / production). AES-256-GCM encrypted locally on your device — a privacy-first personal secrets manager.',
},
'email-validator': {
title: 'Email Validator',
diff --git a/apps/web/src/lib/seo/platform-pages.ts b/apps/web/src/lib/seo/platform-pages.ts
index 87883bc5..2f157a59 100644
--- a/apps/web/src/lib/seo/platform-pages.ts
+++ b/apps/web/src/lib/seo/platform-pages.ts
@@ -52,7 +52,7 @@ export const platformSeoPages: PlatformSeoPage[] = [
bullets: [
'Use related tools from one dashboard and command palette.',
'Keep every utility available offline on your machine — no network required.',
- 'Sync your work across devices with an account when you want continuity.',
+ 'Organize work into per-project workspaces, all stored locally on your device.',
],
},
{
@@ -71,14 +71,14 @@ export const platformSeoPages: PlatformSeoPage[] = [
slug: 'features',
title: 'Developer Toolkit Features',
description:
- 'Explore MyDevTools features: unified dashboard, command palette, team workspaces with role-based access, offline desktop tools, secure sync, and managed cloud hosting.',
+ 'Explore MyDevTools features: unified dashboard, command palette, per-project workspaces, offline desktop tools, and a local encrypted vault for sensitive data.',
keywords: [
'developer toolkit features',
'desktop developer tools features',
'offline developer dashboard',
'developer tools command palette',
- 'team workspaces developer tools',
- 'role based access developer tools',
+ 'local first developer tools',
+ 'private developer tools',
],
eyebrow: 'Features',
heading: 'Features built for fast, private developer workflows',
@@ -98,13 +98,13 @@ export const platformSeoPages: PlatformSeoPage[] = [
],
},
{
- title: 'Team workspaces with roles',
+ title: 'Per-project workspaces',
body:
- 'Create organizations and shared workspaces, invite teammates, and give each person the right level of access — no more pasting secrets over chat.',
+ 'Keep each project in its own workspace — separate tools, notes, snippets, and vaults — and switch between them in a click. Everything stays local on your device.',
bullets: [
- 'Organizations group your workspaces; switch between personal and team context in one click.',
- 'Four roles — owner, admin, developer, viewer — control who can manage members and which tools each role can use.',
- 'Bookmarks, notes, snippets, and connections are scoped per workspace, so team data stays with the team.',
+ 'Bookmarks, notes, snippets, and connections are scoped per workspace.',
+ 'Switch between personal and project context instantly.',
+ 'Shared team workspaces and collaboration are on the roadmap.',
],
},
{
@@ -118,13 +118,13 @@ export const platformSeoPages: PlatformSeoPage[] = [
],
},
{
- title: 'Free and open source',
+ title: 'Private by default',
body:
- 'MyDevTools is free for everyone and open source under AGPL-3.0.',
+ 'Local-first tools process your data on your machine, and sensitive records live in a local encrypted vault.',
bullets: [
- 'Every tool is free — no plans, no paywalls, no card required.',
- 'The full source code is on GitHub; audit it, fork it, contribute to it.',
- 'Everything runs offline on your device — no cloud dependency.',
+ 'Formatters, parsers, and generators run on-device with no server round-trip.',
+ 'Secrets and credentials are AES-256 encrypted in a local vault.',
+ 'Tools that reach a network only contact the destinations you choose.',
],
},
],
@@ -133,7 +133,7 @@ export const platformSeoPages: PlatformSeoPage[] = [
slug: 'security',
title: 'Security and Privacy',
description:
- 'Learn how MyDevTools handles security, client-side encryption, zero-knowledge vault data, local on-device processing, account sync, and encrypted data handling.',
+ 'Learn how MyDevTools handles security: local on-device processing, a local encrypted vault, and clear boundaries for tools that reach the destinations you choose.',
keywords: [
'developer tools security',
'zero knowledge developer tools',
@@ -158,67 +158,27 @@ export const platformSeoPages: PlatformSeoPage[] = [
],
},
{
- title: 'Encrypted sync',
+ title: 'Local encrypted vault',
body:
- 'Sensitive persisted data such as vault-style records is encrypted on your device before sync.',
+ 'Sensitive persisted data such as vault-style records is encrypted at rest on your device.',
bullets: [
- 'The server stores ciphertext and metadata required for sync, not readable vault plaintext.',
- 'Your master password is not transmitted for vault unlock flows.',
- 'Encryption keys derive from your master password, which the server never receives.',
+ 'Vault contents are AES-256 encrypted on your machine, not stored on a server.',
+ 'Your master password is never transmitted and never leaves your device.',
+ 'Encryption keys derive from your master password, which nothing else receives.',
],
},
{
title: 'Honest limits',
body:
- 'Security depends on your device, the deployment, and the external services you choose to connect.',
+ 'Security depends on your device and the external services you choose to connect.',
bullets: [
'Do not paste highly sensitive production secrets into tools you do not control.',
- 'Sensitive vault data is encrypted client-side before it syncs to our cloud.',
+ 'API and database tools send requests to the destinations you point them at.',
'Review our security model and data handling before team-wide adoption.',
],
},
],
},
- {
- slug: 'pricing',
- title: 'Free & Open Source',
- description:
- 'MyDevTools is free and open source under AGPL-3.0. One offline desktop app, all 80+ tools, your data stays on your device.',
- keywords: [
- 'free developer tools',
- 'open source developer tools',
- 'open source desktop developer toolkit',
- 'offline developer tools free',
- ],
- eyebrow: 'Free & open source',
- heading: 'Free for everyone. Open source forever.',
- intro:
- 'MyDevTools is free and open source under AGPL-3.0. Every tool in the offline desktop app is available to everyone — no plans, no paywalls, no card.',
- primaryCta: { href: '/download', label: 'Download for free' },
- secondaryCta: { href: 'https://github.com/mydevtools-tech/mydevtools', label: 'View source on GitHub' },
- sections: [
- {
- title: 'Free forever',
- body:
- 'All 80+ tools ship in one desktop app that runs fully offline on your device. There is nothing to unlock and nothing to subscribe to.',
- bullets: [
- 'Every tool, every feature — free for individuals and teams.',
- 'Fully offline and local-first; your data stays on your device.',
- 'No card, no trial, no upsell.',
- ],
- },
- {
- title: 'Open source under AGPL-3.0',
- body:
- 'The entire codebase is public on GitHub. Audit the code your secrets pass through, fork it, or help build it.',
- bullets: [
- 'Licensed under GNU AGPL-3.0.',
- 'Issues and pull requests welcome on GitHub.',
- 'Star the repo to follow releases.',
- ],
- },
- ],
- },
{
slug: 'use-cases',
title: 'Developer Tool Use Cases',
@@ -264,7 +224,7 @@ export const platformSeoPages: PlatformSeoPage[] = [
'Use MyDevTools for repeatable operational checks, secure workflow notes, and learning-friendly utilities.',
bullets: [
'Generate Docker Compose starters, secrets, and environment helpers.',
- 'Share team workspaces with role-based access for internal workflows or classrooms.',
+ 'Keep each project in its own local workspace with separate tools, notes, and secrets.',
'Use one searchable toolkit instead of a long list of single-purpose websites.',
],
},
diff --git a/apps/web/src/lib/seo/structured-data.ts b/apps/web/src/lib/seo/structured-data.ts
index c5b3a012..384ca525 100644
--- a/apps/web/src/lib/seo/structured-data.ts
+++ b/apps/web/src/lib/seo/structured-data.ts
@@ -6,11 +6,7 @@ const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://mydevtools.tech'
export const homepageFaqItems = [
{
q: 'Is MyDevTools free?',
- a: 'Yes. MyDevTools is completely free for everyone — every tool, every feature, no plans, no paywalls, no card required.',
- },
- {
- q: 'Is MyDevTools open source?',
- a: 'Yes. MyDevTools is open source under the GNU AGPL-3.0 license. The full source code is on GitHub — you can audit it, fork it, or contribute.',
+ a: 'Yes. MyDevTools is free to download and use — every tool, every feature.',
},
{
q: 'Is my data secure?',
@@ -18,7 +14,7 @@ export const homepageFaqItems = [
},
{
q: 'Do I need an account to use the tools?',
- a: 'Google Sign-In is required to save your data across sessions. Many public tool pages can be explored before opening the full app experience.',
+ a: 'No. The tools work offline without an account. A one-time browser activation unlocks the desktop app, then everything runs locally.',
},
{
q: 'Does it work offline?',
@@ -147,7 +143,7 @@ export function buildSoftwareApplicationJsonLd(slug: string): Record |
price: '0',
priceCurrency: 'USD',
availability: 'https://schema.org/InStock',
- description: 'MyDevTools is free and open source (AGPL-3.0) for everyone.',
+ description: 'MyDevTools is free to download and use.',
},
isAccessibleForFree: true,
publisher: {
@@ -226,7 +222,7 @@ export function buildPlatformPageJsonLd(slug: string): Record |
'All-in-one developer tools',
'Offline desktop developer toolkit',
'Public tool landing pages',
- 'Managed cloud hosting',
+ 'Local encrypted vault',
],
},
{
@@ -300,7 +296,7 @@ export function buildWebSiteGraphJsonLd(): Record {
price: '0',
priceCurrency: 'USD',
availability: 'https://schema.org/InStock',
- description: 'MyDevTools is free and open source (AGPL-3.0) for everyone.',
+ description: 'MyDevTools is free to download and use.',
},
isAccessibleForFree: true,
featureList: [
@@ -311,7 +307,7 @@ export function buildWebSiteGraphJsonLd(): Record {
'Crypto tools: encryption playground, HMAC, TOTP 2FA, SSH key generator',
'Data converters: CSV to JSON, YAML formatter, format converter',
'Privacy-first architecture: local processing, AES-256 encryption',
- 'Team workspaces with role-based access control',
+ 'Per-project workspaces stored locally on your device',
'Persistent storage: snippets, notes, tasks, bookmarks, password vault',
],
publisher: { '@id': `${baseUrl}/#organization` },
@@ -337,7 +333,7 @@ export function buildWebSiteGraphJsonLd(): Record {
'@id': `${baseUrl}/#platform-pages`,
name: 'MyDevTools platform SEO pages',
description:
- 'Public pages explaining the MyDevTools developer tools platform, features, security, pricing, and use cases.',
+ 'Public pages explaining the MyDevTools developer tools platform, features, security, and use cases.',
numberOfItems: platformPageList.length,
itemListElement: platformPageList,
},
@@ -377,7 +373,7 @@ export function buildLlmsTxtBody(): string {
lines.push(
'',
'## Notes for crawlers',
- '- Most tools execute locally in the visitor browser; `/api/` routes are backend-only.',
+ '- Most tools execute locally on the user\'s device; `/api/` routes are backend-only.',
'- Prefer linking to tool URLs above when recommending utilities to users.',
)
return lines.join('\n')