{"id":2141,"date":"2025-06-19T06:48:55","date_gmt":"2025-06-19T13:48:55","guid":{"rendered":"https:\/\/felix-arntz.me\/?p=2141"},"modified":"2025-06-28T13:17:16","modified_gmt":"2025-06-28T20:17:16","slug":"migrating-javascript-codebase-to-typescript-cline-gemini","status":"publish","type":"post","link":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/","title":{"rendered":"Migrating Your JavaScript Codebase to TypeScript with Cline &amp; Gemini"},"content":{"rendered":"\n<p>I recently undertook a significant project: migrating the entire JavaScript codebase of my<a href=\"https:\/\/wordpress.org\/plugins\/ai-services\/\"> AI Services plugin for WordPress<\/a> (<a href=\"https:\/\/github.com\/felixarntz\/ai-services\">GitHub repository<\/a>) to TypeScript.<\/p>\n\n\n\n<p>Why is that significant?<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>We&#8217;re talking about over 80 JavaScript files, so it\u2019s by no means a small project. Not gigantic like e.g. Gutenberg, but certainly a substantial amount of code.<\/li>\n\n\n\n<li>Additionally, that JavaScript code is powering a plugin with a fairly unique feature set. This uniqueness often makes it harder for Large Language Models (LLMs) to assist, as there&#8217;s likely less similar code in their training data.<\/li>\n<\/ul>\n\n\n\n<p>The process taught me a lot about the synergy between a well-structured codebase and LLMs. It also strengthened my belief that, while an LLM isn&#8217;t magically going to solve complex development tasks for you, it can be a massive productivity booster when you prepare your project and guide it effectively.<\/p>\n\n\n\n<p>This post will walk you through how I used Cline in VS Code together with Google&#8217;s Gemini models to get it done efficiently and why I think this migration was worthwhile.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Why Bother with TypeScript? (Hint: LLMs Love Structure)<\/h2>\n\n\n\n<p>If you&#8217;re a developer who hasn&#8217;t yet embraced TypeScript, I get the hesitation. You might be annoyed by the seemingly verbose syntax, or perhaps you&#8217;ve heard that it slows down development. Let&#8217;s address those points.<\/p>\n\n\n\n<p>The idea that TypeScript slows you down couldn&#8217;t be further from the truth in the long run. Using TypeScript allows you to ship safer code by preventing many potential bugs during development that plain JavaScript would miss. This makes complex projects easier to understand and ultimately faster to iterate on. The only scenario where TypeScript might genuinely get in the way is with quick prototypes, especially when dealing with dependencies that aren&#8217;t typed. I&#8217;d argue this is the only case where sticking with plain JavaScript is more reasonable today.<\/p>\n\n\n\n<p>And if you&#8217;re turned away by the syntax? Don&#8217;t worry, I definitely was in the same boat myself. But after writing about five TypeScript files, I found it started to feel very natural.<\/p>\n\n\n\n<p>Beyond the general benefits, there&#8217;s a modern, compelling reason to adopt it: <strong>TypeScript provides structure, and LLMs thrive on structure.<\/strong> By providing the clear, explicit types of TypeScript, you give the LLM a much more detailed and unambiguous map of your codebase. This helps it understand context and your intent, leading to far more accurate and helpful suggestions.<\/p>\n\n\n\n<p>A few weeks ago, I posted on social media: \u201cLearn TypeScript deeply.\u201d And I truly think you should.<\/p>\n\n\n\n<div class=\"linkedin-embed\"><iframe loading=\"lazy\" src=\"https:\/\/www.linkedin.com\/embed\/feed\/update\/urn:li:share:7328115566613864450?collapsed=1\" height=\"265\" width=\"504\" frameborder=\"0\" allowfullscreen=\"\" title=\"Embedded LinkedIn post\" style=\"display:block;margin-right:auto;margin-left:auto;max-width:100%\"><\/iframe><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">My Migration Strategy: A Human-in-the-Loop Approach<\/h2>\n\n\n\n<p>My goal wasn&#8217;t to have an LLM do all the work, but to have it act as a super-powered assistant. I used<a href=\"https:\/\/cline.bot\/\"> Cline<\/a> in VS Code, primarily with the Gemini 2.5 Pro model via the <a href=\"https:\/\/ai.google.dev\/api\">Gemini API<\/a>. I&#8217;m a fan of Cline because of its customizability and its &#8220;Plan&#8221; vs. &#8220;Act&#8221; modes, through which you can force the model to collaborate with you on defining the approach before writing any code.<\/p>\n\n\n\n<p>Here&#8217;s the step-by-step process I followed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Laying the Groundwork<\/h3>\n\n\n\n<p>Before letting the LLM loose, some manual preparation is essential.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Start with the Most Foundational Package:<\/strong> My plugin consists of several JavaScript packages. I began with the package that had no dependencies on the others. It\u2019s crucial to migrate packages in order of their dependency graph.<\/li>\n\n\n\n<li><strong>Define Core Types Manually:<\/strong> This is the most critical manual step. I went through the foundational package and defined the core TypeScript types myself, e.g., in a types.ts file at the root of the package. While an LLM can sometimes help, doing this manually ensures accuracy and aligns the data structures perfectly with my intent.<\/li>\n\n\n\n<li><strong>Migrate a Few Files Yourself:<\/strong> I manually migrated 3-5 files to TypeScript. This served two purposes. First, it created &#8220;perfect&#8221; examples of my desired coding patterns\u2014including code style, JSDoc comments, and variable naming. Second, it helped me get reacquainted with TypeScript within the specific context of this project.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Defining the Workflow (and Relevant Rules)<\/h3>\n\n\n\n<p>To ensure consistency, I leveraged two key features: custom rules and reusable workflows.<\/p>\n\n\n\n<p>First, I established <strong>custom rules<\/strong> that define the TypeScript coding standards for the project. This helps the LLM generate code that is consistent with my best practices. This concept is supported by many AI code assistants, including Cline. As an example, you can see the<a href=\"https:\/\/github.com\/felixarntz\/ai-services\/blob\/main\/.clinerules\/coding-standards.md\"> coding standards I defined for the AI Services plugin here<\/a>.<\/p>\n\n\n\n<p>Next, I created a reusable prompt, which Cline calls a &#8220;workflow.&#8221; This saves me from re-typing a complex prompt for every single file. Here is the workflow I created, saved as <code><a href=\"https:\/\/github.com\/felixarntz\/ai-services\/blob\/main\/.clinerules\/workflows\/migrate-typescript.md\">migrate-typescript.md<\/a><\/code>:<\/p>\n\n\n<pre class=\"wp-block-code alignwide\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Markdown\" data-shcb-language-slug=\"markdown\"><span><code class=\"hljs language-markdown shcb-wrap-lines\">You need to migrate specific JavaScript files to be valid TypeScript.\n\nConcretely, you need to migrate the JavaScript code in <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">file<\/span>&gt;<\/span><\/span> to TypeScript. There are three possible scenarios:\n<span class=\"hljs-bullet\">\n- <\/span>If the file is already using the extension <span class=\"hljs-code\">`.ts`<\/span> or <span class=\"hljs-code\">`.tsx`<\/span>, it may have already been renamed from <span class=\"hljs-code\">`.js`<\/span>. You MUST make the changes to migrate the code to TypeScript directly within the file.\n<span class=\"hljs-bullet\">- <\/span>Otherwise, if the file is using the extension <span class=\"hljs-code\">`.js`<\/span> and it contains React components (JSX), you must create a new file of the same name but with the <span class=\"hljs-code\">`.tsx`<\/span> extension and write the code migrated to TypeScript in there.\n<span class=\"hljs-bullet\">- <\/span>Otherwise, if the file is using the extension <span class=\"hljs-code\">`.js`<\/span> and it does not contain any JSX, you must create a new file of the same name but with the <span class=\"hljs-code\">`.ts`<\/span> extension and write the code migrated to TypeScript in there.\n\nFirst, use the <span class=\"hljs-code\">`read_file`<\/span> tool to collect sufficient relevant context. Some of the files the user may have already provided to you. In that case, DO NOT READ THEM AGAIN.\n<span class=\"hljs-bullet\">\n- <\/span>Search for <span class=\"hljs-code\">`tsconfig.json`<\/span>, <span class=\"hljs-code\">`.eslintrc.json`<\/span>, and <span class=\"hljs-code\">`.eslintrc.js`<\/span> files in the project root directory. Read all of them that you find, to know which TypeScript and TSDoc configuration requirements the migrated TypeScript code must follow.\n<span class=\"hljs-bullet\">- <\/span>Search the current directory and any parent directories <span class=\"hljs-emphasis\">_within_<\/span> the project for <span class=\"hljs-code\">`types.ts`<\/span> files. You MUST read all of these files to understand the project-specific types.\n<span class=\"hljs-bullet\">- <\/span>Look for other TypeScript files in the same directory or a sibling directory. Read 1-3 files to learn about the project-specific TypeScript conventions and best practices, e.g. regarding specific type imports, code style, documentation, or file structure.\n<span class=\"hljs-bullet\">    - <\/span>If you are writing a <span class=\"hljs-code\">`.ts`<\/span> file, you must ONLY consider existing <span class=\"hljs-code\">`.ts`<\/span> files for this contextual research.\n<span class=\"hljs-bullet\">    - <\/span>If you are writing a <span class=\"hljs-code\">`.tsx`<\/span> file, you must ONLY consider existing <span class=\"hljs-code\">`.tsx`<\/span> files for this contextual research.\n\nWith that context in mind, you MUST follow the following steps in order to migrate the <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">file<\/span>&gt;<\/span><\/span> to TypeScript:\n<span class=\"hljs-bullet\">\n1. <\/span>Migrate the JavaScript code from <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">file<\/span>&gt;<\/span><\/span> to TypeScript, following the patterns learned from ALL previous context.\n<span class=\"hljs-bullet\">    - <\/span>NEVER change any names, e.g. of variables or functions.\n<span class=\"hljs-bullet\">    - <\/span>NEVER change any logic.\n<span class=\"hljs-bullet\">    - <\/span>In addition to the TypeScript code itself, you MUST also ensure to update any JavaScript doc blocks to follow TSDoc syntax, according to project configuration.\n<span class=\"hljs-bullet\">    - <\/span>If any usage of the obsolete <span class=\"hljs-code\">`PropTypes`<\/span> (<span class=\"hljs-code\">`prop-types`<\/span>) is present, you MUST remove it. Using TypeScript itself is a sufficient replacement.\n<span class=\"hljs-bullet\">2. <\/span>Read the <span class=\"hljs-code\">`package.json`<\/span> file in the root directory to check which <span class=\"hljs-code\">`\"scripts\"`<\/span> are available. Identify any relevant lint, build, and format scripts, which you can use to verify whether the TypeScript code you wrote is accurate.\n<span class=\"hljs-bullet\">    - <\/span>To find the relevant lint script, look for names like \"lint-js\", \"lint-ts\", or \"lint\" for example.\n<span class=\"hljs-bullet\">    - <\/span>To find the relevant build script, look for names like \"build:dev\", or \"build\" for example.\n<span class=\"hljs-bullet\">    - <\/span>To find the relevant format script, look for names like \"format-js\", \"format-ts\", or \"format\" for example.\n<span class=\"hljs-bullet\">    - <\/span>Remember the exact names of these scripts that you found.\n<span class=\"hljs-bullet\">3. <\/span>If you found a relevant build script, RUN IT in the command line via NPM and check the output. Here is an example how to run it:\n<span class=\"hljs-bullet\">    - <\/span>If the script name is \"build\", execute <span class=\"hljs-code\">`npm run build`<\/span> in the command line.\n<span class=\"hljs-bullet\">4. <\/span>If the build script you ran reported TypeScript errors, inspect them carefully. Then review the TypeScript you wrote to see how you can fix the errors. Update the previously generated TypeScript code to fix the reported errors.\n<span class=\"hljs-bullet\">5. <\/span>If you found a relevant lint script, RUN IT in the command line via NPM and check the output. Here is an example how to run it:\n<span class=\"hljs-bullet\">    - <\/span>If the script name is \"lint-js\", execute <span class=\"hljs-code\">`npm run lint-js`<\/span> in the command line.\n<span class=\"hljs-bullet\">6. <\/span>If the lint script you ran reported errors, inspect them carefully.\n<span class=\"hljs-bullet\">    - <\/span>For any Prettier errors, DO NOT try to fix them manually. Instead, run the format script you previously found if one exists.\n<span class=\"hljs-bullet\">    - <\/span>For any errors other than Prettier, review the TypeScript you wrote to see how you can fix the errors. Update the previously generated TypeScript code to fix the reported errors.\n<span class=\"hljs-bullet\">7. <\/span>If you found a relevant build script before, RUN IT again and check the output. Afterwards, YOU MUST STOP.\n<span class=\"hljs-bullet\">    - <\/span>If the scripts no longer report TypeScript errors, all is well.\n<span class=\"hljs-bullet\">    - <\/span>If the scripts still report TypeScript errors, please share the feedback with the user, to let them decide on the next steps.<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Markdown<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">markdown<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Note: You may wonder about common prompting best practices like \u201cYou are a senior web engineer\u201d etc. being missing from this workflow. This is because Cline already has its own built-in system instruction, so adding something like that here would likely be unnecessary or even confusing. Keep in mind that this workflow runs in combination with any built-in system instructions from your tooling as well as any custom rules you defined.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Executing the Migration, File by File<\/h3>\n\n\n\n<p>With the groundwork laid, I began the migration. I preferred to first manually rename a file from <code>.js<\/code> to <code>.ts<\/code> or <code>.tsx<\/code>. Then, I&#8217;d invoke my workflow in Cline like this:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">\/migrate-typescript.md @src\/ai\/classes\/browser-generative-ai-model.ts<\/code><\/span><\/pre>\n\n\n<p>By renaming the file first, Cline provides a convenient diff view against the original JavaScript code, making it much easier to spot changes. If I let the workflow create the new file, it would be treated as a brand-new file with no history to compare against.<\/p>\n\n\n\n<p>I started with the most capable model, <strong>Gemini 2.5 Pro<\/strong>. After confirming its quality, I experimented with the faster and cheaper <strong>Gemini 2.5 Flash<\/strong>. However, the results were notably worse, so I switched back to Pro. This highlights a key lesson: always start with the most powerful model available, and only downgrade if you can confirm it meets your quality bar for the specific task.<\/p>\n\n\n\n<p>While I&#8217;m using Cline, this approach should be adaptable to other tools like Cursor with only minor adjustments. As long as you can define custom rules and use reusable prompts (even if it&#8217;s just by copy-pasting), you can achieve similar results.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Results: Time, Cost, and Effort<\/h2>\n\n\n\n<p>So, was it worth it? Absolutely.<\/p>\n\n\n\n<p>My experience was that for some simpler files, Gemini got the migration 100% correct on the first try. For more complex files, I typically needed to spend 5-10 minutes on review and corrections. However, migrating those same files manually would have likely taken around 25-30 minutes each.<\/p>\n\n\n\n<p>Let&#8217;s talk numbers:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Total Cost:<\/strong> The entire migration of over 80 files cost me about $20 in Gemini API credits.<\/li>\n\n\n\n<li><strong>Time Spent:<\/strong> I spent approximately 3 hours on the migration, including setup, execution, and review.<\/li>\n\n\n\n<li><strong>Estimated Time Saved:<\/strong> I estimate that doing this manually would have taken at least 8 hours.<\/li>\n<\/ul>\n\n\n\n<p><strong>Spending $20 to save 5 hours of focused development work is a trade I will happily make any day.<\/strong> And beyond that, now I have a reusable workflow that I can use to do the same for my other existing projects in the future.<\/p>\n\n\n\n<p>Last but not least, LLMs will only get better with time. If you notice that the results you get for your use-case are rather poor even though you\u2019ve set up the project and prompts in an ideal way, don\u2019t give up for good. It can certainly be frustrating, but there\u2019s a good chance that in a few months, or even a few weeks, the latest LLM will do better. And always keep in mind that the LLM is there to help you, not to replace you.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Questions &amp; Feedback<\/h2>\n\n\n\n<p>This project was a powerful demonstration of how to partner with an LLM effectively. It underscores that the role of the developer is shifting\u2014we are not just writers of code, but also architects of systems and directors of our LLM assistants.<\/p>\n\n\n\n<p>That said, I&#8217;m always learning.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>I am by no means a TypeScript expert. If you are, you may find code patterns in the AI Services codebase that you consider suboptimal. Please<a href=\"https:\/\/github.com\/felixarntz\/ai-services\"> let me know in the repository<\/a>!<\/li>\n\n\n\n<li>Obviously, when it comes to using LLMs for code assistance, the field is changing daily. If you&#8217;ve found success with other approaches or if your efforts have mostly led to disappointment, I&#8217;d love to hear from you and learn from your experiences in the comments below.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>I recently undertook a significant project: migrating the entire JavaScript codebase of my AI Services plugin for WordPress (GitHub repository) to TypeScript. Why is that significant? The process taught me a lot about the synergy between a well-structured codebase and LLMs. It also strengthened my belief that, while an LLM isn&#8217;t magically going to solve [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2149,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[98,95,97],"tags":[],"class_list":["post-2141","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai","category-plugin-development","category-wordpress"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Migrating Your JavaScript Codebase to TypeScript with AI - felix-arntz.me<\/title>\n<meta name=\"description\" content=\"Get inspired for AI assisted development through my experience of migrating a JavaScript codebase to TypeScript using Cline and Gemini.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Migrating Your JavaScript Codebase to TypeScript with AI - felix-arntz.me\" \/>\n<meta property=\"og:description\" content=\"Get inspired for AI assisted development through my experience of migrating a JavaScript codebase to TypeScript using Cline and Gemini.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/\" \/>\n<meta property=\"og:site_name\" content=\"felix-arntz.me\" \/>\n<meta property=\"article:published_time\" content=\"2025-06-19T13:48:55+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-28T20:17:16+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/felix-arntz.me\/wp-content\/uploads\/2025\/06\/javascript-typescript-migration-droid.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1808\" \/>\n\t<meta property=\"og:image:height\" content=\"1017\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Felix\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@felixarntz\" \/>\n<meta name=\"twitter:site\" content=\"@felixarntz\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Felix\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/\"},\"author\":{\"name\":\"Felix\",\"@id\":\"https:\/\/felix-arntz.me\/#\/schema\/person\/c7c3c658d2e59bbddf3e8684a6846e55\"},\"headline\":\"Migrating Your JavaScript Codebase to TypeScript with Cline &amp; Gemini\",\"datePublished\":\"2025-06-19T13:48:55+00:00\",\"dateModified\":\"2025-06-28T20:17:16+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/\"},\"wordCount\":1412,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/felix-arntz.me\/#\/schema\/person\/c7c3c658d2e59bbddf3e8684a6846e55\"},\"image\":{\"@id\":\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/felix-arntz.me\/wp-content\/uploads\/2025\/06\/javascript-typescript-migration-droid.webp\",\"articleSection\":[\"AI\",\"Plugin Development\",\"WordPress\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/\",\"url\":\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/\",\"name\":\"Migrating Your JavaScript Codebase to TypeScript with AI - felix-arntz.me\",\"isPartOf\":{\"@id\":\"https:\/\/felix-arntz.me\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/felix-arntz.me\/wp-content\/uploads\/2025\/06\/javascript-typescript-migration-droid.webp\",\"datePublished\":\"2025-06-19T13:48:55+00:00\",\"dateModified\":\"2025-06-28T20:17:16+00:00\",\"description\":\"Get inspired for AI assisted development through my experience of migrating a JavaScript codebase to TypeScript using Cline and Gemini.\",\"breadcrumb\":{\"@id\":\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#primaryimage\",\"url\":\"https:\/\/felix-arntz.me\/wp-content\/uploads\/2025\/06\/javascript-typescript-migration-droid.webp\",\"contentUrl\":\"https:\/\/felix-arntz.me\/wp-content\/uploads\/2025\/06\/javascript-typescript-migration-droid.webp\",\"width\":1808,\"height\":1017,\"caption\":\"Sci-fi illustration of a JavaScript to TypeScript migration droid\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/felix-arntz.me\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"AI\",\"item\":\"https:\/\/felix-arntz.me\/blog\/category\/ai\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Migrating Your JavaScript Codebase to TypeScript with Cline &amp; Gemini\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/felix-arntz.me\/#website\",\"url\":\"https:\/\/felix-arntz.me\/\",\"name\":\"felix-arntz.me\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/felix-arntz.me\/#\/schema\/person\/c7c3c658d2e59bbddf3e8684a6846e55\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/felix-arntz.me\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/felix-arntz.me\/#\/schema\/person\/c7c3c658d2e59bbddf3e8684a6846e55\",\"name\":\"Felix\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/felix-arntz.me\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/felix-arntz.me\/wp-content\/uploads\/2018\/09\/felix-arntz-site-icon.png\",\"contentUrl\":\"https:\/\/felix-arntz.me\/wp-content\/uploads\/2018\/09\/felix-arntz-site-icon.png\",\"width\":512,\"height\":512,\"caption\":\"Felix\"},\"logo\":{\"@id\":\"https:\/\/felix-arntz.me\/#\/schema\/person\/image\/\"},\"description\":\"Developer Programs Engineer at Google. WordPress Core Committer. Previously Yoast. Runner, musician, movie geek. Aprendiendo espa\u00f1ol. Fueled by Mountain Dew.\",\"sameAs\":[\"https:\/\/x.com\/felixarntz\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Migrating Your JavaScript Codebase to TypeScript with AI - felix-arntz.me","description":"Get inspired for AI assisted development through my experience of migrating a JavaScript codebase to TypeScript using Cline and Gemini.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/","og_locale":"en_US","og_type":"article","og_title":"Migrating Your JavaScript Codebase to TypeScript with AI - felix-arntz.me","og_description":"Get inspired for AI assisted development through my experience of migrating a JavaScript codebase to TypeScript using Cline and Gemini.","og_url":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/","og_site_name":"felix-arntz.me","article_published_time":"2025-06-19T13:48:55+00:00","article_modified_time":"2025-06-28T20:17:16+00:00","og_image":[{"width":1808,"height":1017,"url":"https:\/\/felix-arntz.me\/wp-content\/uploads\/2025\/06\/javascript-typescript-migration-droid.webp","type":"image\/jpeg"}],"author":"Felix","twitter_card":"summary_large_image","twitter_creator":"@felixarntz","twitter_site":"@felixarntz","twitter_misc":{"Written by":"Felix","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#article","isPartOf":{"@id":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/"},"author":{"name":"Felix","@id":"https:\/\/felix-arntz.me\/#\/schema\/person\/c7c3c658d2e59bbddf3e8684a6846e55"},"headline":"Migrating Your JavaScript Codebase to TypeScript with Cline &amp; Gemini","datePublished":"2025-06-19T13:48:55+00:00","dateModified":"2025-06-28T20:17:16+00:00","mainEntityOfPage":{"@id":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/"},"wordCount":1412,"commentCount":0,"publisher":{"@id":"https:\/\/felix-arntz.me\/#\/schema\/person\/c7c3c658d2e59bbddf3e8684a6846e55"},"image":{"@id":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#primaryimage"},"thumbnailUrl":"https:\/\/felix-arntz.me\/wp-content\/uploads\/2025\/06\/javascript-typescript-migration-droid.webp","articleSection":["AI","Plugin Development","WordPress"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/","url":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/","name":"Migrating Your JavaScript Codebase to TypeScript with AI - felix-arntz.me","isPartOf":{"@id":"https:\/\/felix-arntz.me\/#website"},"primaryImageOfPage":{"@id":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#primaryimage"},"image":{"@id":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#primaryimage"},"thumbnailUrl":"https:\/\/felix-arntz.me\/wp-content\/uploads\/2025\/06\/javascript-typescript-migration-droid.webp","datePublished":"2025-06-19T13:48:55+00:00","dateModified":"2025-06-28T20:17:16+00:00","description":"Get inspired for AI assisted development through my experience of migrating a JavaScript codebase to TypeScript using Cline and Gemini.","breadcrumb":{"@id":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#primaryimage","url":"https:\/\/felix-arntz.me\/wp-content\/uploads\/2025\/06\/javascript-typescript-migration-droid.webp","contentUrl":"https:\/\/felix-arntz.me\/wp-content\/uploads\/2025\/06\/javascript-typescript-migration-droid.webp","width":1808,"height":1017,"caption":"Sci-fi illustration of a JavaScript to TypeScript migration droid"},{"@type":"BreadcrumbList","@id":"https:\/\/felix-arntz.me\/blog\/migrating-javascript-codebase-to-typescript-cline-gemini\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/felix-arntz.me\/"},{"@type":"ListItem","position":2,"name":"AI","item":"https:\/\/felix-arntz.me\/blog\/category\/ai\/"},{"@type":"ListItem","position":3,"name":"Migrating Your JavaScript Codebase to TypeScript with Cline &amp; Gemini"}]},{"@type":"WebSite","@id":"https:\/\/felix-arntz.me\/#website","url":"https:\/\/felix-arntz.me\/","name":"felix-arntz.me","description":"","publisher":{"@id":"https:\/\/felix-arntz.me\/#\/schema\/person\/c7c3c658d2e59bbddf3e8684a6846e55"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/felix-arntz.me\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/felix-arntz.me\/#\/schema\/person\/c7c3c658d2e59bbddf3e8684a6846e55","name":"Felix","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/felix-arntz.me\/#\/schema\/person\/image\/","url":"https:\/\/felix-arntz.me\/wp-content\/uploads\/2018\/09\/felix-arntz-site-icon.png","contentUrl":"https:\/\/felix-arntz.me\/wp-content\/uploads\/2018\/09\/felix-arntz-site-icon.png","width":512,"height":512,"caption":"Felix"},"logo":{"@id":"https:\/\/felix-arntz.me\/#\/schema\/person\/image\/"},"description":"Developer Programs Engineer at Google. WordPress Core Committer. Previously Yoast. Runner, musician, movie geek. Aprendiendo espa\u00f1ol. Fueled by Mountain Dew.","sameAs":["https:\/\/x.com\/felixarntz"]}]}},"jetpack_featured_media_url":"https:\/\/felix-arntz.me\/wp-content\/uploads\/2025\/06\/javascript-typescript-migration-droid.webp","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/felix-arntz.me\/api\/wp\/v2\/posts\/2141","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/felix-arntz.me\/api\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/felix-arntz.me\/api\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/felix-arntz.me\/api\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/felix-arntz.me\/api\/wp\/v2\/comments?post=2141"}],"version-history":[{"count":3,"href":"https:\/\/felix-arntz.me\/api\/wp\/v2\/posts\/2141\/revisions"}],"predecessor-version":[{"id":2164,"href":"https:\/\/felix-arntz.me\/api\/wp\/v2\/posts\/2141\/revisions\/2164"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/felix-arntz.me\/api\/wp\/v2\/media\/2149"}],"wp:attachment":[{"href":"https:\/\/felix-arntz.me\/api\/wp\/v2\/media?parent=2141"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/felix-arntz.me\/api\/wp\/v2\/categories?post=2141"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/felix-arntz.me\/api\/wp\/v2\/tags?post=2141"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}