<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Emma Alder</title>
    <description>The latest articles on DEV Community by Emma Alder (@emmaalder).</description>
    <link>https://dev.to/emmaalder</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1358230%2Fd7b37f40-0284-4ec5-9aa5-4904cfb444f9.png</url>
      <title>DEV Community: Emma Alder</title>
      <link>https://dev.to/emmaalder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emmaalder"/>
    <language>en</language>
    <item>
      <title>These are the best large language models for coding</title>
      <dc:creator>Emma Alder</dc:creator>
      <pubDate>Mon, 24 Feb 2025 10:49:01 +0000</pubDate>
      <link>https://dev.to/hackmamba/these-are-the-best-large-language-models-for-coding-1co2</link>
      <guid>https://dev.to/hackmamba/these-are-the-best-large-language-models-for-coding-1co2</guid>
      <description>&lt;p&gt;As software developers, we dream of effortless coding, where we can transform complex problems into elegant and performant solutions. ⁤⁤⁤⁤However, software development is a complicated process, and writing multiple lines of error-free code is challenging, even for the most experienced developer. ⁤⁤Hence, pair programming, where two programmers work together simultaneously and provide feedback to each other, has been popular in software development.&lt;/p&gt;

&lt;p&gt;⁤⁤Traditionally, one programmer writes the code while the other reviews each line, providing real-time feedback and suggestions. ⁤⁤With the rapid adoption of artificial intelligence (AI), pair programming with AI has enabled a single developer to write code quickly, enhancing their efficiency, improving code quality, facilitating rapid learning, and boosting overall productivity. &lt;/p&gt;

&lt;p&gt;Today, developers can access an impressive range of tools built on top of large language models (LLMs) that go beyond basic code autocompletion and provide powerful AI-assisted coding experience. Even though OpenAI’s GPT-4o is leading most of the benchmarks for coding, Anthropic Claude and Google’s Gemini are not far behind. In this article, we’ll go through the best LLMs available for software development and use most of these LLMs interchangeably with &lt;a href="https://sourcegraph.com/cody" rel="noopener noreferrer"&gt;Sourcegraph’s Cody&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of popular AI Coding Assistants
&lt;/h2&gt;

&lt;p&gt;Various coding tools with high-level languages are available to improve the coding experience. The integrated development environment (IDE) has streamlined the coding process by providing a comprehensive suite of tools, including a code editor, debugger, and compiler, all within a single interface. Developers can easily switch the environment according to their coding preferences for various programming languages. &lt;/p&gt;

&lt;p&gt;The integration of artificial intelligence for assisted coding started with the basic autocompletion features that predict and complete code snippets based on context. Later, more advanced code completion tools, such as &lt;a href="https://learn.microsoft.com/en-us/visualstudio/ide/using-intellisense" rel="noopener noreferrer"&gt;Microsoft IntelliSense&lt;/a&gt;, &lt;a href="https://www.kite.com/blog/product/kite-is-saying-farewell/" rel="noopener noreferrer"&gt;Kite&lt;/a&gt;, and &lt;a href="https://www.tabnine.com/" rel="noopener noreferrer"&gt;Tabnine&lt;/a&gt;, were introduced with advanced machine learning models. Some of the most popular coding tools available today with advanced machine learning models are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://sourcegraph.com/cody" rel="noopener noreferrer"&gt;Sourcegraph Cody&lt;/a&gt; is a popular tool that uses multiple LLMs and advanced code search and analysis capabilities to enhance developers' understanding of code and generation.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt; was conceptualized from the success of OpenAI's GPT-3 as a code completion tool, with the first technical preview made available in June 2021 within the Visual Studio code development environment. Github Copilot is a proprietary tool that is available as a subscription-based service for developers. Since 2023, GitHub Copilot has used GPT models, such as GPT-4.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.tabnine.com/" rel="noopener noreferrer"&gt;Tabnine&lt;/a&gt; is a proprietary tool that leverages AI to provide code completions for various programming languages, helping speed up the development process and increase productivity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are also a few open-source models, such as code llama. However, most of them use the same LLMs, such as &lt;a href="https://openai.com/" rel="noopener noreferrer"&gt;OpenAI GPT-4&lt;/a&gt;, &lt;a href="https://www.anthropic.com/" rel="noopener noreferrer"&gt;Anthropic's Claude&lt;/a&gt;, &lt;a href="https://mistral.ai/" rel="noopener noreferrer"&gt;Mistral AI&lt;/a&gt;, &lt;a href="https://gemini.google.com/" rel="noopener noreferrer"&gt;Google Gemini&lt;/a&gt;, and others, for code and chat suggestions. Before diving into the most suitable LLMs for your development workflow, let's understand how these large transformer-based models work.&lt;/p&gt;

&lt;h2&gt;
  
  
  How LLMs work
&lt;/h2&gt;

&lt;p&gt;A language model is usually a generative model used to understand and generate natural language in machine learning. Large language models have huge parameters (in millions, billions, or even trillions) and use deep learning architecture called transformers. These models are trained on very large datasets to predict the probability of a sequence of words paying attention to input sequences. Hence, these models use a self-attention mechanism that captures dependencies and relationships between the input sequence to process and generate a data sequence.&lt;/p&gt;

&lt;p&gt;A wide variety of large language models and multimodel LLMs are available; some of the most popular are as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://openai.com/" rel="noopener noreferrer"&gt;OpenAI's GPT-4&lt;/a&gt; is a 1 trillion parameter model, significantly improving GPT-3's (175 billion parameters). GPT-4 is still the leading model in many benchmarks. It provides a context window in two versions, i.e., 8,192 and 32,768 tokens.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gemini.google.com/" rel="noopener noreferrer"&gt;Google's Gemini&lt;/a&gt; is the successor to &lt;a href="https://blog.google/technology/ai/lamda/" rel="noopener noreferrer"&gt;LaMDA&lt;/a&gt; and &lt;a href="https://ai.google/discover/palm2" rel="noopener noreferrer"&gt;PaLM2&lt;/a&gt;. Gemini 1.5 can handle up to 2 million tokens.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.anthropic.com/" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt; Claude 2, &lt;a href="https://claude.ai/" rel="noopener noreferrer"&gt;Claude 3.5 sonnet&lt;/a&gt;, focuses on ethical considerations and safety.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://llama.meta.com/docs/model-cards-and-prompt-formats" rel="noopener noreferrer"&gt;Meta Llama 3&lt;/a&gt; are open-source models available in 8B, 70B, and 405B versions.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://mistral.ai/" rel="noopener noreferrer"&gt;Mistral&lt;/a&gt; AI Mixtral 8 X 7B and 8 X 22 B models and other variant models are also available for download for general and specialized purposes. Mixtral is also an open source LLMs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All of these powerful models are trained on code-related data and can generate code and perform other coding tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  How code is generated with LLMs
&lt;/h2&gt;

&lt;p&gt;A large language model uses natural language descriptions or prompts with enough context to perform a natural language processing task. Developers can fine-tune such models for coding-related tasks such as generating, debugging, etc. LLMs can demonstrate the ability to understand syntax, coding styles, and programming practices across multiple programming languages. &lt;/p&gt;

&lt;p&gt;Given the previous tokens and prompts relevant to the tasks, the weights of these models are fine-tuned on these datasets to predict the next token in a sequence. This fine-tuning helps the transformer-based model generate coherent and context-relevant content. &lt;/p&gt;

&lt;p&gt;Generating sound output from an LLM depends on the &lt;strong&gt;training data, the model's parameters, and good prompting&lt;/strong&gt;. Vast and diverse code-related datasets from various sources, such as open-source repositories, documentation, online resources, coding books, tutorials, and coding forums, such as stack overflow, are used to train code generation. &lt;/p&gt;

&lt;p&gt;Coding assistants like &lt;a href="https://sourcegraph.com/cody" rel="noopener noreferrer"&gt;Cody&lt;/a&gt; use different models for various code-related tasks, such as real-time code generation, code completion, and code analysis, to help with debugging, refactoring, writing test cases, and code optimization tasks. They also offer chat interfaces to ask code-related questions, discuss and troubleshoot problems, and inspire developers with solutions. &lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison of LLMs
&lt;/h2&gt;

&lt;p&gt;Large language models and foundational models such as GPT-4, Gemini, Claude, and Mistral are versatile and unpredictable, which makes evaluating their performance complex and challenging. However, many organizations design specific benchmarks to provide a standardized, rigorous framework for comparing the capabilities of LLMs across core language-related tasks. &lt;/p&gt;

&lt;p&gt;Most benchmarks consist of carefully designed tasks such as question answering, logical reasoning, numerical reasoning, code generation, and other natural language processing tasks. For example, &lt;a href="https://arxiv.org/pdf/2009.03300" rel="noopener noreferrer"&gt;Massive Multitask Language Understanding (MMLU)&lt;/a&gt; is a comprehensive benchmark designed to test an LLM's ability to understand and answer questions across various subjects. Similarly, &lt;a href="https://gluebenchmark.com/leaderboard" rel="noopener noreferrer"&gt;Glue&lt;/a&gt; and &lt;a href="https://super.gluebenchmark.com/leaderboard/" rel="noopener noreferrer"&gt;SuperGlue&lt;/a&gt; are other popular benchmarks for testing general language understanding. &lt;/p&gt;

&lt;p&gt;Benchmarks also require the selection of appropriate metrics for comparison; accuracy, BLEU score, and perplexity are the most common ones, while some other benchmarks also use human judgment for contrast.&lt;/p&gt;

&lt;p&gt;Different challenges and benchmarks evaluate models for various purposes. Some benchmarks, such as &lt;a href="https://arxiv.org/abs/1803.05457" rel="noopener noreferrer"&gt;ARC (AI2 Reasoning Challenge)&lt;/a&gt;, evaluate LLMs’ ability to reason for complex, multi-step science problems. While benchmarks such as &lt;a href="https://arxiv.org/pdf/2109.07344" rel="noopener noreferrer"&gt;GSM8K (Grade School Math 8K)&lt;/a&gt; assess an LLM's math problem-solving skills. These benchmarks have enabled competition and the development of models with knowledge on par with school or college graduates.&lt;/p&gt;

&lt;p&gt;Most benchmarks are focused on language and academic capability; however, there are a few benchmarks that evaluate programming-related tasks. The following image from the &lt;a href="https://bigcode-bench.github.io/" rel="noopener noreferrer"&gt;big code bench leaderboard&lt;/a&gt; evaluates LLMs with various practical and challenging programming tasks, including code generation and code completion based on natural language descriptions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xk42ovz02zp2e1fyj7s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xk42ovz02zp2e1fyj7s.png" alt="Leaderboard for BigCodeBench-Complete" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This leaderboard shows that the GPT-4 Turbo tops the chart, followed by the Claude 3.5 Sonnet and other models. Gemini 1.5, Mistral, and GPT-4o are also among the top 10. Diverse sets of benchmarks and leaderboards are available to test LLM coding ability comprehensively. Here are some selected coding benchmarks testing different LLMs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://evalplus.github.io/leaderboard.html" rel="noopener noreferrer"&gt;EvalPlus leaderboard&lt;/a&gt; evaluates AI coders with rigorous tests. GPT4-Turbo also tops the chart here.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://huggingface.co/spaces/lmsys/chatbot-arena-leaderboard" rel="noopener noreferrer"&gt;Chatbot arena leaderboard&lt;/a&gt; collected over 1,000,000 human pairwise comparisons to rank LLMs with the Bradley-Terry model and display the model ratings in Elo-scale. ChatGPT-4o ranks first, followed by Gemini-1.5 Pro, Claude 3.5 Sonnet, Meta Llama, and Mistral AI Large, among the top models.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://evo-eval.github.io/" rel="noopener noreferrer"&gt;Evo-Eval&lt;/a&gt;: Due to the popularity and age of other benchmarks, many are prone to data leakage, where example solutions for code can be readily found online. Evo-Eval transforms existing coding benchmarks (for example, HumanEval) into problems in domains such as difficulty, creativity, subtleness, etc. Here’s how the model ranks in the image below:
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxv450lujp36b8h20dnsx.png" alt="Coding Benchmark, Evo-Eval, GPT-4 Turbo, Claude" width="800" height="103"&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/taoyds/spider" rel="noopener noreferrer"&gt;Spider&lt;/a&gt; and &lt;a href="https://github.com/defog-ai/sql-eval" rel="noopener noreferrer"&gt;SQL-Eval&lt;/a&gt; are large-scale, complex, and cross-domain benchmarks for text-to-SQL tasks. Spider measures how well the generated SQL code or query retrieves the correct data from the database. SQL-Eval measures SQL code complexity and semantic diversity and ensures the generated queries are syntactically correct and meaningful. GPT-4 is used in most of the leading models in their &lt;a href="https://yale-lily.github.io/spider" rel="noopener noreferrer"&gt;leaderboards&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Strengths and weakness of LLM models
&lt;/h2&gt;

&lt;p&gt;Each LLM has its strengths and weaknesses. Many benchmarks test the ability to generate code in different scenarios to understand the LLM's strengths and weaknesses. The following provides a detailed overview of the strengths and weaknesses of the most used LLMs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1d0y3lrvxvbfj6npzmv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1d0y3lrvxvbfj6npzmv.png" alt="strengths and weaknesses of LLM models" width="800" height="511"&gt;&lt;/a&gt;&lt;br&gt;
Based on the above results, here is our ranking of these LLMS: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;OpenAI’s GPT-4 and GPT-4o: As it performs the best across multiple benchmarks&lt;/li&gt;
&lt;li&gt;Anthropic Claude 3.5 Sonnet: It is second to GPT-4 &amp;amp; GPT-4o in most of the benchmarks and also more accurate in different scenarios&lt;/li&gt;
&lt;li&gt;Google’s Gemini 1.5: It is more factual and less imaginative than GPT-4, and it might fail in some scenarios requiring a more creative coding approach.&lt;/li&gt;
&lt;li&gt;Mistral AI: Fast but has a comparably short context window&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Over time as these models’ architecture improves and is trained on more data, this ranking is likely to change. Hence, we need a coding assistant that allows us to easily switch between these models. Sourcegraph’s AI assistant, Cody, can integrate with our favorite IDEs and allow us to change LLMs interchangeably.&lt;/p&gt;
&lt;h2&gt;
  
  
  Integrating LLMs with Cody
&lt;/h2&gt;

&lt;p&gt;There are a large number and variations of LLMs, each with its own strengths and weaknesses. Cody, Sourcegraph’s AI assistant, can use different LLMs to help developers understand, write, and fix code more efficiently. Using multiple advanced LLMs allows Cody to provide fast single and multiple-line code completion. If you haven't used Cody yet, you can sign up for free to get started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing Cody&lt;/strong&gt;&lt;br&gt;
Cody provides seamless integration with IDEs and code editors of your choice; it can be integrated into Microsoft Visual Studio Code, JetBrains IntelliJ IDEA, PhpStorm, PyCharm, WebStorm, RubyMine, GoLand, Google Android Studio, and NeoVim.&lt;br&gt;
For Visual Studio Code IDE integration, you can get the Cody extension from the marketplace. Alternatively, you can open the page by clicking &lt;strong&gt;View &amp;gt; Extensions in VS code and searching for Cody AI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7f4d6i91tyrln0zj25w4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7f4d6i91tyrln0zj25w4.png" alt="Installing Cody from VS code Marketplace" width="800" height="207"&gt;&lt;/a&gt;&lt;br&gt;
When you install Cody in Microsoft Visual Studio for the first time, it is usually the last item in the sidebar. Check for the icon, as shown in the image below. You’ll need to sign in using the same login method and ID you used while creating your account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foc37fprcj8dkltqqbggu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foc37fprcj8dkltqqbggu.png" alt="sign in" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press the button again. You'll get a Cody chat sidebar, which you can use to chat with Cody to generate code, document your code, explain parts of code, write unit tests, find code smells, and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn6zwqxwrqctphsssrxsn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn6zwqxwrqctphsssrxsn.png" alt="Cody Chat bar" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Switching LLMs within Cody&lt;/strong&gt;&lt;br&gt;
After installing Cody in VS Code, you can select between different LLMs through the drop-down menu below the Cody: Chat bar prompt box. Each model has its strengths and weaknesses, as previously discussed. However, Cody has grouped different models for accuracy, speed, or best of both. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq808ybgqt0dlvuq53qzv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq808ybgqt0dlvuq53qzv.png" alt="Available LLMs in Cody Chat bar" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s the &lt;a href="https://sourcegraph.com/docs/cody/clients/install-vscode#supported-llm-models" rel="noopener noreferrer"&gt;list of LLMs supported by Cody&lt;/a&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;a href="https://www.anthropic.com/" rel="noopener noreferrer"&gt;Anthropic Claude &lt;/a&gt;&lt;/th&gt;
&lt;th&gt;&lt;a href="https://openai.com/" rel="noopener noreferrer"&gt;Open AI GPT&lt;/a&gt;&lt;/th&gt;
&lt;th&gt;&lt;a href="https://gemini.google.com/" rel="noopener noreferrer"&gt;Google Gemini&lt;/a&gt;&lt;/th&gt;
&lt;th&gt;&lt;a href="https://mistral.ai/technology/#models" rel="noopener noreferrer"&gt;Mistral AI&lt;/a&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude 3.5 Sonnet&lt;/td&gt;
&lt;td&gt;GPT-4o&lt;/td&gt;
&lt;td&gt;Gemini 1.5 Pro&lt;/td&gt;
&lt;td&gt;Mixtral-8x22B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude 3 Sonnet&lt;/td&gt;
&lt;td&gt;GPT-4 Turbo&lt;/td&gt;
&lt;td&gt;Gemini 1.5 Flash&lt;/td&gt;
&lt;td&gt;Mixtral 8x7B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude 3 Opus&lt;/td&gt;
&lt;td&gt;GPT-3.5 Turbo&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude 3 Haiku&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The integration of these models provides several benefits to the programmers for AI-assisted software development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cody recommends that users select different options for better accuracy of code, faster generation speed, or balance. Thus, users can easily choose their preferences without researching each LLM.&lt;/li&gt;
&lt;li&gt;LLMs enable Cody to provide more accurate and context-aware code completions and debugging.&lt;/li&gt;
&lt;li&gt;LLMs empower Cody to understand code semantics better. As a result, it can explain complex code constructs, algorithms, and design patterns.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Using LLM models in Cody for code generation tasks
&lt;/h2&gt;

&lt;p&gt;The following code example illustrates how Cody integrations allow experimenting with different LLMs to solve coding problems:&lt;/p&gt;

&lt;p&gt;Generating algorithm to solve a Leet code problem:&lt;br&gt;&lt;br&gt;
Let’s experiment with the problem: &lt;a href="https://leetcode.com/problems/longest-substring-without-repeating-characters/description/" rel="noopener noreferrer"&gt;Longest substring without repeating characters&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7y455v84vgafettefqn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7y455v84vgafettefqn.png" alt="Leet Code Problem: Generating the Longest Substring without repeating characters" width="800" height="676"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the description and put it in the chat or prompt in Cody using Claude 3.5 Sonnet. Cody will generate the solution that passes all the test cases. In this case, we are writing Python code. Here’s the code output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjo1zm440vy0e2kpdmrxj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjo1zm440vy0e2kpdmrxj.png" alt="Anthropic Claude 3.5 Sonnet generates verbose output with explanation and code complexity" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code passes all the test cases. Claude is quite detailed in its generation as it generates additional details and explanations of how the code works in the chat and the space and time complexity. Different LLMs will result in various output formats. Using the same prompt with Gemini 1.5 Pro generates the following code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zbccq5xdtypsog7fxio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zbccq5xdtypsog7fxio.png" alt="Code Generated with Gemini" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using GPT-o, we get the following output with an explanation of the code and example usage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjilfgpkesmj044mfrmlt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjilfgpkesmj044mfrmlt.png" alt="GPT4-o generates verbose output with explanation and example usage" width="800" height="746"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The runtime for all the generations is in milliseconds, and none of the syntax errors in the generated code are present.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generate code to train a deep-learning model&lt;/strong&gt;&lt;br&gt;
Training AI models is a common coding task these days. AI training AI models is another goal for automated coding systems. Using the following prompt, we can generate functioning Python code to train an object detection model.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Generate Python code to create and train a deep learning model for object detection using PyTorch. The code should include the following steps: &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Import necessary libraries and modules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define the dataset and data loaders. Here, images are available in the dataset folder, while the annotations are provided in a json file, as mentioned in the &lt;a href="https://cocodataset.org/" rel="noopener noreferrer"&gt;Coco dataset&lt;/a&gt; website.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use a pre-trained neural network model suitable for object detection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define the loss function and optimizer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement the training loop with validation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Save the trained model.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Ensure the code is well-commented and follows best practices for readability and efficiency.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's the code generated by Claude 3.5 Sonnet model; sections are capped to reduce the lengthy code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import torch
import torchvision
...

# Step 1: Import necessary libraries and modules
import torch.optim as optim
from tqdm import tqdm

# Step 2: Define the dataset and data loaders
class CocoDataset(Dataset):
    def __init__(self, root_dir, annotation_file, transform=None):
        self.root_dir = root_dir
        self.coco = COCO(annotation_file)
        ...

# Create dataset and data loaders
train_dataset = CocoDataset(root_dir='dataset/train', annotation_file='annotations/instances_train2017.json')
val_dataset = CocoDataset(root_dir='dataset/val', annotation_file='annotations/instances_val2017.json')

train_loader = DataLoader(train_dataset, batch_size=2, shuffle=True, num_workers=4, collate_fn=lambda x: tuple(zip(*x)))
val_loader = DataLoader(val_dataset, batch_size=2, shuffle=False, num_workers=4, collate_fn=lambda x: tuple(zip(*x)))

# Step 3: Use a pretrained neural network model suitable for object detection
def get_model(num_classes):
    model = fasterrcnn_resnet50_fpn(pretrained=True)
    in_features = model.roi_heads.box_predictor.cls_score.in_features
    ...

# Step 4: Define the loss function and optimizer
params = [p for p in model.parameters() if p.requires_grad]
optimizer = optim.SGD(params, lr=0.005, momentum=0.9, weight_decay=0.0005)

# Step 5: Implement the training loop with validation
num_epochs = 10
for epoch in range(num_epochs):
    model.train()
    train_loss = 0
    for images, targets in tqdm(train_loader, desc=f"Epoch {epoch+1}/{num_epochs}"):
        ...

# Step 6: Save the trained model
torch.save(model.state_dict(), 'object_detection_model.pth')
print("Model saved successfully!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code works as expected, with slight adjustments to correct the format in the project directory and some minor error fixing. Again, the model generates additional explanations, such as before, explaining the code generation and the assumptions the LLM model has made. GPT4-o, Gemini, and Mixtral also give very similar results, requiring some fundamental changes to the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Integrating large language models in IDEs has transformed software development by enhancing efficiency, improving code quality, and facilitating rapid learning and prototyping. These advanced tools use LLMs to provide real-time code completion, code generation, explanation, debugging, and understanding features. &lt;/p&gt;

&lt;p&gt;Among all the popular models, GPT-4o leads many coding benchmarks, and Claude 3.5 Sonnet is among the top five models in these benchmarks. &lt;strong&gt;Claude 3.5 and Mixtral-8X7B are extremely fast, while GPT-4o and Gemini work well with multimodal inputs.&lt;/strong&gt; Each model has its strengths and weaknesses, and different scenarios may require different models.&lt;/p&gt;

&lt;p&gt;Cody allows you to find the best-fitting LLM for the coding scenario and your organization’s coding practices. Whether you are looking for speed, accuracy, or balance, Cody’s adaptable integrations have you covered. You can start experimenting today with multiple LLMs, from GPT-4 to Claude 3.5, directly available from &lt;a href="https://sourcegraph.com/cody" rel="noopener noreferrer"&gt;Sourcegraph Cody&lt;/a&gt;, and select the best model for your coding problem.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>ai</category>
      <category>coding</category>
      <category>gemini</category>
    </item>
    <item>
      <title>Simplify Your Complex Code Migration Projects With AI</title>
      <dc:creator>Emma Alder</dc:creator>
      <pubDate>Thu, 20 Feb 2025 16:18:46 +0000</pubDate>
      <link>https://dev.to/hackmamba/simplify-your-complex-code-migration-projects-with-ai-3fn8</link>
      <guid>https://dev.to/hackmamba/simplify-your-complex-code-migration-projects-with-ai-3fn8</guid>
      <description>&lt;p&gt;Remember when Reddit faced the challenge of migrating 2,000 Git repositories? This wasn’t a routine transition. It required detailed planning to prevent downtime and operational disruption while addressing technical complexities like repository structure and scalability.&lt;/p&gt;

&lt;p&gt;Like Reddit’s experience, &lt;a href="https://docs.sourcegraph.com/@4.4/admin/migration" rel="noopener noreferrer"&gt;code migration&lt;/a&gt; has become critical for organizations modernizing their systems to stay competitive. These migrations introduce significant operational and architectural challenges, particularly in distributed systems and legacy architectures. Businesses risk data compatibility issues, delays, and rising costs without careful management.&lt;/p&gt;

&lt;p&gt;This guide explores how AI tools can simplify complex migrations while maintaining efficiency and business continuity. Let’s begin by examining the common obstacles organizations face during code migrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key challenges in code migration
&lt;/h2&gt;

&lt;p&gt;Compared to Reddit’s migration of 2,000 repositories, the stakes are even higher for organizations transitioning from monolithic architectures to microservices.&lt;/p&gt;

&lt;p&gt;Here’s what makes large-scale migrations so challenging:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keeping systems running smoothly&lt;/strong&gt;&lt;br&gt;
Maintaining uptime during a migration is no small feat. It often means juggling feature flags, parallel systems, and complex database transitions while avoiding disruptions to everyday operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Balancing data integrity and change&lt;/strong&gt;&lt;br&gt;
As data models evolve, preserving integrity across versions becomes a puzzle. Backward compatibility and rolling out new features demand sophisticated transformation layers and constant oversight.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Navigating business impacts&lt;/strong&gt;&lt;br&gt;
Poor planning can bring operations to a halt. When &lt;a href="https://sourcegraph.com/case-studies/factset-migrates-from-perforce-to-github" rel="noopener noreferrer"&gt;FactSet migrated from Perforce to GitHub&lt;/a&gt;, they had to anticipate potential compatibility issues and avoid bottlenecks in their development cycles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Managing dependencies and integrations&lt;/strong&gt;&lt;br&gt;
Today’s applications are interconnected ecosystems. Version mismatches, deprecated APIs, third-party updates, and overlooked security patches can create ripple effects that disrupt entire systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time, resources, and human effort&lt;/strong&gt;&lt;br&gt;
Traditional migrations often rely heavily on manual labor. This slows progress and increases the risk of errors, inflates costs, and delays the launch of new features.&lt;/p&gt;

&lt;p&gt;These challenges underline why migrations are often seen as challenging. But with the right tools, they don’t have to be. Let’s examine how AI can simplify these complexities and deliver better outcomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How AI simplifies code migration
&lt;/h2&gt;

&lt;p&gt;AI tools automate migration tasks, reduce errors, and accelerate delivery. Here’s how they help:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Understanding code in context&lt;/strong&gt;&lt;br&gt;
AI analyzes codebases to identify patterns and dependencies, making tasks like API migrations seamless. In the screenshot, the AI suggests precise updates with added features based on context.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5e9ye8kejf5k3dnxpuws.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5e9ye8kejf5k3dnxpuws.png" alt="AI understand code in context" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Driving business impact&lt;/strong&gt;&lt;br&gt;
AI speeds up migrations by 60%, cuts bugs, and boosts productivity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Faster migrations: &lt;a href="https://sourcegraph.com/case-studies/factset-migrates-from-perforce-to-github" rel="noopener noreferrer"&gt;FactSet reduced repository analysis&lt;/a&gt; times while moving to GitHub.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fewer bugs: AI catches issues missed in manual reviews, reducing technical debt.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Higher productivity: Automating repetitive tasks improves PR merge times and developer satisfaction.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refactoring at scale&lt;br&gt;
AI applies consistent fixes across large codebases. For instance, Reddit used AI to detect anti-patterns and &lt;a href="https://www.reddit.com/r/RedditEng/comments/1bdtrjq/wrangling_2000_git_repos_at_reddit/?rdt=53948" rel="noopener noreferrer"&gt;refactor the 2,000 repositories&lt;/a&gt; efficiently (see example in screenshot).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9r7phxlaron54s8tdjr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9r7phxlaron54s8tdjr.png" alt="How AI automates refactoring" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Improving transparency&lt;/strong&gt;&lt;br&gt;
AI maps dependencies, predicts change impacts and generates logs to simplify troubleshooting and handovers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning and adapting&lt;/strong&gt;&lt;br&gt;
AI evolves with every migration, suggesting better patterns, flagging risks, and aligning with coding standards.&lt;/p&gt;

&lt;p&gt;Next, we’ll explore specific migration types AI can handle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of code migrations AI can handle
&lt;/h2&gt;

&lt;p&gt;Some of the code migration tasks that AI can include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Language version upgrades&lt;/strong&gt;&lt;br&gt;
Upgrading language versions, like Python 2 to Python 3 or Java 8 to Java 11, is a common migration scenario. AI excels at identifying and transforming syntax changes, deprecated features, and API modifications, just like this example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5noj0vxvq6x4k7aivigg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5noj0vxvq6x4k7aivigg.png" alt="Language version upgrade" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Framework migrations&lt;/strong&gt;&lt;br&gt;
Whether transitioning from Angular.js to Angular or Spring to Micronaut, AI tools can understand framework-specific patterns and generate equivalent code. For example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qfu8zpevcyslfjljwyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qfu8zpevcyslfjljwyh.png" alt="Framework migration" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database schema migrations&lt;/strong&gt;&lt;br&gt;
AI systems have become particularly adept at handling database migrations, including schema changes, ORM updates, and query optimizations. AI can analyze existing database structures and generate appropriate migration scripts while maintaining data integrity:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gfq7pobcd0gwq9v4ew4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gfq7pobcd0gwq9v4ew4.png" alt="Database schema migration" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architectural transformations&lt;/strong&gt;&lt;br&gt;
One of the most complex migrations involves architectural changes, such as moving from monolithic to microservices architecture. AI tools can analyze dependencies, suggest service boundaries, and help maintain system functionality during the transition:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24tlyx1tup2ty46dyw4c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24tlyx1tup2ty46dyw4c.png" alt="Architectural transformation" width="800" height="579"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next section will show you steps to automate your migration process. Let us get into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating code migration: A step-by-step AI guide
&lt;/h2&gt;

&lt;p&gt;To follow this guide, we’ll use Sourcegraph’s code intelligence AI, which includes prompts and custom commands. These features allow you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work with context-aware prompts tailored to your codebase.&lt;/li&gt;
&lt;li&gt;Apply best practices across multiple programming languages.&lt;/li&gt;
&lt;li&gt;Choose from different generative models for flexibility and precision.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before starting, make sure Sourcegraph is set up in your code editor. For installation instructions, refer to the &lt;a href="https://sourcegraph.com/docs/cody" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With these tools in place, let’s walk-through how to automate code migrations efficiently and reduce risks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 1: Initial assessment and planning&lt;/strong&gt;&lt;br&gt;
Sourcegraph's AI analyzes repository structures, dependencies, and code patterns to build a comprehensive migration strategy. For example, it can scan your codebase and automatically identify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deprecated API usage patterns&lt;/li&gt;
&lt;li&gt;Legacy framework dependencies&lt;/li&gt;
&lt;li&gt;Outdated language features&lt;/li&gt;
&lt;li&gt;Complex inheritance hierarchies&lt;/li&gt;
&lt;li&gt;Technical debt hotspots&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can configure it to identify specific patterns relevant to your migration using custom commands or prompts. The example below shows how I prompted Sourcegraph AI with context to my codebase to draft out my migration strategy:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipvpl3cvqsy0cr6af40b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fipvpl3cvqsy0cr6af40b.png" alt="Migration strategy" width="800" height="1012"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 2: Defining migration rules&lt;/strong&gt;&lt;br&gt;
Sourcegraph's AI intelligent prompting system allows you to define clear migration rules through natural language. For instance, we will ask the AI to provide rules for its migration strategy so that workflows will not be broken, downtimes will be curbed, and the transition will be easy.  &lt;/p&gt;

&lt;p&gt;The results in the image below are migration rules to follow while implementing the migration strategies that the AI tool generated earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq3201tpzlb0ircullczf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq3201tpzlb0ircullczf.png" alt="Migration rules" width="800" height="959"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 3: Staged migration execution&lt;/strong&gt;&lt;br&gt;
The migration process is executed in carefully planned stages, with the AI providing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Context-aware transformations:&lt;/strong&gt; Sourcegraph’s AI understands the full context of your code, ensuring changes maintain business logic and system integrity. When transforming code, it considers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Surrounding code context&lt;/li&gt;
&lt;li&gt;Import dependencies&lt;/li&gt;
&lt;li&gt;Function relationships&lt;/li&gt;
&lt;li&gt;Error handling patterns&lt;/li&gt;
&lt;li&gt;State management&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Intelligent code smell detection:&lt;/strong&gt; Throughout the migration, the AI identifies potential issues like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redundant code patterns&lt;/li&gt;
&lt;li&gt;Performance bottlenecks&lt;/li&gt;
&lt;li&gt;Security vulnerabilities&lt;/li&gt;
&lt;li&gt;Inconsistent error handling&lt;/li&gt;
&lt;li&gt;Resource leaks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At this stage, we can create personalized prompts or custom commands for the features or changes we want to make in the codebase. We can also use the chat feature, pass the file(s) in question as context, and add our prompt so Sourcegraph’s AI will give us a new version of that piece or group of code. Here is an example to fix the error handling issue the AI detected as an anti-pattern in our code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExOXl6cGxqNHI2MDFvYTFzMnp1NjI5b296dTN1MmNoamlmdmtscjc5NSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2F1idSmugp7AOh1UEz6s%2Fgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia3.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExOXl6cGxqNHI2MDFvYTFzMnp1NjI5b296dTN1MmNoamlmdmtscjc5NSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2F1idSmugp7AOh1UEz6s%2Fgiphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 4: Validation and testing&lt;/strong&gt;&lt;br&gt;
Sourcegraph's AI advanced validation capabilities ensure the migration's success through automated tests. In this phase, we can create a prompt/custom command or use the chat interface to generate unit tests for any module, function, or service in our new migration code. For the new error-handling service in the migration, here is a sample prompt to write tests for it using AI:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExa3lzN2tmd2ZwejlzN3ozc2V5eHp0dTV2ZjBsZDhyYjV4cjRsdThsYSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FDPTVdHMzl7yxDw87De%2Fgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExa3lzN2tmd2ZwejlzN3ozc2V5eHp0dTV2ZjBsZDhyYjV4cjRsdThsYSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2FDPTVdHMzl7yxDw87De%2Fgiphy.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices for secure code migrations
&lt;/h2&gt;

&lt;p&gt;A robust security framework must be implemented throughout migration to protect sensitive data, maintain compliance, and ensure business continuity. Here are some security and compliance best practices for code migration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Conduct extensive testing before migration, including performance stress testing to validate system behavior under load and staged rollouts to minimize risk. Ensure a comprehensive strategy with clear rollback procedures for immediate execution if needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Outline scope, timeline, and impacts to identify potential business disruptions and mitigation strategies. Track changes via version control with audit trails and use &lt;a href="https://community.atlassian.com/t5/Atlassian-Migration-Program/Migration-Runbook/ba-p/1728726" rel="noopener noreferrer"&gt;migration runbooks&lt;/a&gt; for consistent, error-free execution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure firewalls to secure source and target environments. Maintain environment isolation by separating development, staging, and production with proper access controls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define emergency response procedures for handling issues during migration. Establish communication protocols to keep stakeholders informed and escalation paths to engage relevant teams quickly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While we look at the general best practices, we should also consider the security implications of the AI tool we use in the migration process. Some of the essential security measures used by Sourcegraph to protect your code are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data Protection and Encryption: &lt;a href="https://sourcegraph.com/docs/cody/core-concepts/cody-gateway" rel="noopener noreferrer"&gt;Sourcegraph Cody Gateway&lt;/a&gt; avoids storing sensitive data and retains only diagnostic data for rate-limiting and error tracking, configurable in &lt;a href="https://sourcegraph.com/docs/admin/config/site_config" rel="noopener noreferrer"&gt;account settings&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Compliance Monitoring: &lt;a href="https://sourcegraph.com/docs/cody/enterprise/features#guardrails" rel="noopener noreferrer"&gt;Guardrails&lt;/a&gt; enforce coding standards and prevent AI from replicating copyrighted code using verification mechanisms.&lt;/li&gt;
&lt;li&gt;Self-Hosting: Enterprises can self-host Sourcegraph AI for complete control, following this &lt;a href="https://sourcegraph.com/docs/cody/core-concepts/enterprise-architecture" rel="noopener noreferrer"&gt;setup guidance&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;As organizations grow their systems, complex code migrations pose significant challenges, from maintaining system continuity to managing data integrity and operational impacts. Without careful oversight, businesses risk disruptions and increased costs during these transitions. &lt;/p&gt;

&lt;p&gt;AI tools, such as Sourcegraph, can simplify the migration process by automating error-prone tasks and enhancing code quality, thereby reducing completion times by &lt;a href="https://hopp.tech/resources/data-migration-blog/ai-driven-migration/" rel="noopener noreferrer"&gt;up to 60%&lt;/a&gt; and improving developer productivity.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://sourcegraph.com/cody/chat" rel="noopener noreferrer"&gt;Sourcegraph&lt;/a&gt; today to begin your journey toward faster, more secure, and more efficient code migrations.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>migration</category>
      <category>complexcode</category>
      <category>programming</category>
    </item>
    <item>
      <title>Typesafe PostgreSQL queries with Kysely and Neon</title>
      <dc:creator>Emma Alder</dc:creator>
      <pubDate>Sat, 16 Mar 2024 23:05:40 +0000</pubDate>
      <link>https://dev.to/hackmamba/typesafe-postgresql-queries-with-kysely-and-neon-493</link>
      <guid>https://dev.to/hackmamba/typesafe-postgresql-queries-with-kysely-and-neon-493</guid>
      <description>&lt;p&gt;Your database is one of the most critical components of your application, and it’s essential to query it correctly to extract the necessary data. Typesafe database queries allow you to leverage the type system to prevent type errors, catch errors at compile-time, debug easily, and reduce security vulnerabilities. &lt;/p&gt;

&lt;p&gt;This tutorial will walk you through creating a contact management system using &lt;a href="https://kysely.dev/?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;Kysely&lt;/a&gt; and &lt;a href="https://neon.tech/?ref=hm" rel="noopener noreferrer"&gt;Neon PostgreSQL&lt;/a&gt;. The application will introduce you to the fundamentals of typesafe programming using Kysely integrated into the Neon PostgreSQL serverless database.&lt;/p&gt;

&lt;p&gt;By the end of this tutorial, you'll have a functional application and a solid understanding of how to apply typesafe practices in your database interactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are typesafe database queries?
&lt;/h2&gt;

&lt;p&gt;In software development, data integrity is paramount. Ensuring that the data stored in a database is accurate, consistent, and reliable is essential for the proper functioning of any application. &lt;a href="https://programmingsharing.com/type-safe-queries-in-spring-data-jpa-a4ca195d7c37" rel="noopener noreferrer"&gt;Typesafe database queries&lt;/a&gt; play a pivotal role in achieving this data integrity by leveraging the power of static type checking to prevent errors and maintain the overall robustness of the codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  PostgreSQL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; is a powerful, open-source object-relational database management system (ORDBMS) known for its reliability, flexibility, and extensibility. It has gained widespread popularity among developers thanks to its robust feature set, including data integrity, ACID compliance, and extensibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type safety and its significance in database queries
&lt;/h2&gt;

&lt;p&gt;Typesafe query builders provide a type-safe way to construct SQL queries without using an ORM (object-relational mapping) tool. This gives developers more control over their queries and can be a good choice for applications requiring more complex queries.&lt;/p&gt;

&lt;p&gt;Some popular typesafe query builders for JavaScript and TypeScript include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;   Kysely: Kysely is a popular query builder known for its ease of use and support for autocompletion.&lt;/li&gt;
&lt;li&gt;    &lt;a href="https://safeql.dev/?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;safeql&lt;/a&gt;: safeql is a library that validates and auto-generates TypeScript types from raw SQL queries.&lt;/li&gt;
&lt;li&gt;    &lt;a href="https://ts-sql-query.readthedocs.io/en/stable/#gsc.tab=0?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;ts-query-builder&lt;/a&gt;: A simple and lightweight query builder that is easy to start.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this tutorial, we’ll use &lt;strong&gt;Kysely&lt;/strong&gt; as it's easy to use, supports auto-completion for faster development, and integrates seamlessly with Neon serverless Postgres.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Kysely?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://kysely.dev/?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;Kysely&lt;/a&gt; is a TypeScript SQL query builder that guarantees type safety and auto-completion. It is primarily designed for Node.js but can run on &lt;a href="https://deno.com/?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;Deno&lt;/a&gt; and web browsers. Kysely ensures that you only refer to tables and columns visible to the part of the query you're writing. Moreover, the generated result type includes only the selected columns, complete with their correct types and aliases.&lt;/p&gt;

&lt;p&gt;Kysely's &lt;a href="https://kysely.dev/docs/intro?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; features excellent examples of how to use it and guides on how to get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Neon?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://neon.tech/?ref=hm" rel="noopener noreferrer"&gt;Neon&lt;/a&gt; is a serverless Postgres database that separates compute and storage to offer modern developer features such as autoscaling, branching, bottomless storage, and more.&lt;/p&gt;

&lt;p&gt;Refer to the Neon &lt;a href="https://neon.tech/docs/introduction?utm_source=guides&amp;amp;utm_medium=content&amp;amp;utm_campaign=hackmamba" rel="noopener noreferrer"&gt;Get Started&lt;/a&gt; documentation to get up and running in just a few minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub link to view source code
&lt;/h2&gt;

&lt;p&gt;Check out the complete source code &lt;a href="https://github.com/namancoderpro/contact-management-system-db?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contact management system with Kysely and Neon PostgreSQL
&lt;/h2&gt;

&lt;p&gt;To build the CRUD (Create, Read, Update, Delete) contact management system application, you will need a few things:&lt;br&gt;
    - Node.js and npm&lt;br&gt;
    - Familiarity with TypeScript&lt;br&gt;
    - Fundamental SQL and database concepts&lt;/p&gt;

&lt;p&gt;This tutorial uses NodeJs LTS version &lt;code&gt;v20.10.0&lt;/code&gt; and npm version &lt;code&gt;10.2.3&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;To know the versions on your computer, run the following commands:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="c1"&gt;// Get nodeJS version&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="c1"&gt;// Get npm version&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Setting up Neon PostgreSQL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://console.neon.tech/" rel="noopener noreferrer"&gt;Sign up&lt;/a&gt; for &lt;a href="https://neon.tech/docs/introduction/free-tier?ref=hm" rel="noopener noreferrer"&gt;Neon’s free tier&lt;/a&gt; and upgrade to a paid plan when ready to scale.&lt;br&gt;
After signing up, you will be redirected to the Neon console to create your first project. &lt;/p&gt;

&lt;p&gt;Enter a &lt;code&gt;name&lt;/code&gt; for your project, select a &lt;code&gt;Postgres version&lt;/code&gt;, provide a &lt;code&gt;database name&lt;/code&gt;, and select a &lt;code&gt;region&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;When you're done, click &lt;strong&gt;Create Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fepwho2d8fxvyc155e2yr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fepwho2d8fxvyc155e2yr.png" alt="Neon’s create a new project screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You’ll be presented with the connection details for your new project, which you will use to connect to your database from a client or application. You can retrieve them later from the connection details widget on the Neon dashboard.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installing TypeScript and Kysely
&lt;/h2&gt;

&lt;p&gt;TypeScript is a superset of JavaScript, adding static types to the language. It is installed via npm (Node Package Manager).&lt;/p&gt;

&lt;p&gt;Open your terminal and run the following command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt; &lt;span class="nx"&gt;typescript&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;TypeScript is installed globally with the command above, so you can use it in any project.&lt;/p&gt;

&lt;p&gt;Run the following command in your terminal to install Kysely:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;kysely&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For Kysely's query compilation and execution to work, it needs to understand your database's SQL specification and how to communicate with it. This requires a dialect implementation.&lt;/p&gt;

&lt;p&gt;Kysely uses the &lt;code&gt;kysely-neon&lt;/code&gt; dialect for Neon serverless Postgres. Run the following command to install the dialect:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;kysely&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;neon&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To connect to the Neon instance, you need a WebSocket. Install the ws module using the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Perfect — now let’s create our project directory with the following commands:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;mkdir&lt;/span&gt; &lt;span class="nx"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;management&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;system&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, navigate inside this directory with the command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="nx"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;management&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;system&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next, run this command to create a TypeScript project: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;tsc&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That will leave you with a folder structure like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;node_modules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;                      &lt;span class="c1"&gt;// Node modules and dependencies&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="kr"&gt;package&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;                  
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="kr"&gt;package&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;tsconfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally, run these three commands to create the &lt;code&gt;index.ts&lt;/code&gt; file in a &lt;code&gt;src&lt;/code&gt; folder:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

 &lt;span class="nx"&gt;mkdir&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

  &lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

 &lt;span class="nx"&gt;touch&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally, you should have this folder structure as shown below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;contact&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;management&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;system&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;node_modules&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;              &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt; &lt;span class="nx"&gt;modules&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;dependencies&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;                       &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Source&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="nx"&gt;directory&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;               &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Main&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="nx"&gt;point&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;application&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;dist&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;                      &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Compiled&lt;/span&gt; &lt;span class="nx"&gt;JavaScript&lt;/span&gt; &lt;span class="nf"&gt;files &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;generated&lt;/span&gt; &lt;span class="nx"&gt;after&lt;/span&gt; &lt;span class="nx"&gt;TypeScript&lt;/span&gt; &lt;span class="nx"&gt;compilation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="kr"&gt;package&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;               &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;dependency&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="kr"&gt;package&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;          &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Automatically&lt;/span&gt; &lt;span class="nx"&gt;generated&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="nx"&gt;operations&lt;/span&gt; &lt;span class="nx"&gt;where&lt;/span&gt; &lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;modifies&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;node_modules&lt;/span&gt; &lt;span class="nx"&gt;tree&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="kr"&gt;package&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;tsconfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;              &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;TypeScript&lt;/span&gt; &lt;span class="nx"&gt;compiler&lt;/span&gt; &lt;span class="nx"&gt;configuration&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Database schema design
&lt;/h2&gt;

&lt;p&gt;The contact management system requires a simple yet effective database schema. You must create a &lt;code&gt;contacts&lt;/code&gt; table that will store the contact information. The table will have the following fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;id&lt;/code&gt;: A unique identifier for each contact. This will be the primary key. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;: The name of the contact. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;phone&lt;/code&gt;: The phone number of the contact. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;email&lt;/code&gt;: The email address of the contact.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Implementing schema with Kysely
&lt;/h2&gt;

&lt;p&gt;With Kysely, you can define this schema directly in your TypeScript code. Kysely provides a way to define table schemas using TypeScript interfaces, which are then used to generate corresponding SQL queries. Here's how you can define the &lt;code&gt;contacts&lt;/code&gt; table schema using Kysely.&lt;/p&gt;

&lt;p&gt;Note: Use environment variables as a best practice for security and convenience. Refer to this DotEnv article to learn how to use Node environment variables.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;src/index.ts&lt;/code&gt; you will import all the required modules and initialize Kysely with your database connection information. &lt;/p&gt;

&lt;p&gt;This &lt;code&gt;src/index.ts&lt;/code&gt; file will also contain all the application code.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;//index.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;dotenv&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GeneratedAlways&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Kysely&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kysely&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NeonDialect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kysely-neon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ws&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Line 2 - imports the &lt;code&gt;dotenv&lt;/code&gt; module, which allows you to load environment variables from a &lt;code&gt;.env&lt;/code&gt; file into &lt;code&gt;process.env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Line 3 - imports the &lt;code&gt;GeneratedAlways&lt;/code&gt; and &lt;code&gt;Kysely&lt;/code&gt; types from the &lt;code&gt;kysely&lt;/code&gt; module. These types are used for interacting with the database.&lt;/p&gt;

&lt;p&gt;Line 4 - imports the &lt;code&gt;NeonDialect&lt;/code&gt; type from the &lt;code&gt;kysely-neon&lt;/code&gt; module. This type is used to specify the dialect of the database.&lt;/p&gt;

&lt;p&gt;Line 5 - imports the &lt;code&gt;ws&lt;/code&gt; module, which allows you to create WebSocket servers and clients.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;dotenv.config()&lt;/code&gt; line calls the &lt;code&gt;config&lt;/code&gt; function from the &lt;code&gt;dotenv&lt;/code&gt; module, which loads the environment variables from the .env file into process.env.&lt;/p&gt;

&lt;p&gt;Now, let’s move on to the next lines, where the database’s types and tables are declared inside the &lt;code&gt;src/index.ts&lt;/code&gt; as shown below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ContactTable&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ContactTable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GeneratedAlways&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;First, a type for the Database object with &lt;code&gt;interface Database{}&lt;/code&gt; was defined with a &lt;code&gt;contacts&lt;/code&gt; property of type &lt;code&gt;ContactTable&lt;/code&gt;. This interface is used to define the structure of the database.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;interface ContactTable&lt;/code&gt; defines a type for the &lt;code&gt;ContactTable&lt;/code&gt; object, representing the database table.&lt;/p&gt;

&lt;p&gt;After this, we will declare the database, the schema, and a function to create the contacts table within our database.&lt;/p&gt;

&lt;p&gt;As you can see in this code snippet, we declare the &lt;code&gt;db&lt;/code&gt; variable to establish a connection with the database using the connection string, which can be obtained from your Neon console.&lt;/p&gt;

&lt;p&gt;Next, we access the database schema inside the &lt;code&gt;src/index.ts&lt;/code&gt; using &lt;code&gt;db.schema&lt;/code&gt; and then declare a function &lt;code&gt;createContactsTable()&lt;/code&gt; that creates the &lt;code&gt;contacts&lt;/code&gt; table and adds the following columns: &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;phone&lt;/code&gt;, and &lt;code&gt;email&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Kysely&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Database&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;dialect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NeonDialect&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// URL from Neon Connection Dashboard&lt;/span&gt;
        &lt;span class="na"&gt;webSocketConstructor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;

&lt;span class="c1"&gt;// create table&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createContactsTable&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contacts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ifNotExists&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;serial&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;col&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;col&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;primaryKey&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;col&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;col&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notNull&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;phone&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;col&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;col&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notNull&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;col&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;col&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notNull&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;createContactsTable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Implementing the CRUD Operations
&lt;/h2&gt;

&lt;p&gt;Now that we’ve created our table, it’s time to perform CRUD operations on it to create, add, read, update, and delete contacts.&lt;/p&gt;
&lt;h3&gt;
  
  
  Insert
&lt;/h3&gt;

&lt;p&gt;This code snippet will show how you can insert data into the database in a type-safe manner. Add this to the &lt;code&gt;src/index.ts&lt;/code&gt; file itself.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;insertContact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertInto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contacts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nx"&gt;email&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;returning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;insertContact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Kysely Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1234567890&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;qTqQ1@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;insertContact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Neon Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1234567890&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;qTqQ1@example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this code, we created a function &lt;code&gt;insertContact()&lt;/code&gt; and accept the name, phone, and email as arguments to it. Next, we’re inserting into the &lt;code&gt;contacts&lt;/code&gt; table using the &lt;code&gt;insertInto()&lt;/code&gt; function, and the values are taken from &lt;code&gt;insertContacts()&lt;/code&gt;'s arguments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update
&lt;/h3&gt;

&lt;p&gt;Next, let’s create a function to update existing contacts in the database inside &lt;code&gt;src/index.ts&lt;/code&gt; file.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// Update a contact in the database&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateContact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contacts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;returningAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executeTakeFirst&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;updateContact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jane Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1234567890&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;qTqQ1@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This time, the function will take the &lt;code&gt;id&lt;/code&gt; as an argument along with the other fields so that we can point to a specific record and update it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;updateTable()&lt;/code&gt; is an built-in function in Neon to perform update operations. We set the updated fields like regular SQL queries using the &lt;code&gt;set()&lt;/code&gt; function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Delete
&lt;/h3&gt;

&lt;p&gt;After that, the delete function will allow us to remove contacts from our database.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// src/index.ts&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;// Delete a contact from the database&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;deletePerson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deleteFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contacts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;returningAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executeTakeFirst&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;deletePerson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In this case, we only need the &lt;code&gt;id&lt;/code&gt; to remove that specific entry from the database using the &lt;code&gt;deleteFrom()&lt;/code&gt; function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Read
&lt;/h3&gt;

&lt;p&gt;Finally, the &lt;code&gt;getContacts()&lt;/code&gt; function inside the &lt;code&gt;src/index.ts&lt;/code&gt; will allow us to fetch the existing records in the database.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// src/index.ts&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;// Read from the database&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getContacts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contacts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;selectFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;contacts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;selectAll&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contacts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getContacts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To execute the code, you must run the following code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If the code runs without throwing any errors, it means the database transaction has been successfully completed. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3cedhrbeujm4texk56vx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3cedhrbeujm4texk56vx.png" alt="Running npx ts-node in terminal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To check, you can also log into your Neon console, select the project, and navigate to &lt;strong&gt;Tables → contacts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi0q0ot7b8w4eiuso0va.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi0q0ot7b8w4eiuso0va.png" alt="Sample database in Neon"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Error handling and type-safety in TypeScript with Kysely
&lt;/h2&gt;

&lt;p&gt;TypeScript, when used with a typesafe SQL query builder like Kysely, offers several advantages, particularly in the context of error handling and maintaining a robust codebase:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Compile-time error checking:&lt;/strong&gt; TypeScript's static typing system allows for catching type-related errors at compile time. This means issues like passing a string where a number is expected in a query can be identified before the code is run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code clarity and predictability:&lt;/strong&gt; The explicit type definitions in TypeScript make the code more readable and understandable. It's clearer what data type is expected and returned by each function or operation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-completion and intelliSense:&lt;/strong&gt; Modern IDEs use TypeScript's type information to provide better auto-completion, which reduces the likelihood of typos and incorrect method calls that could lead to runtime errors.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Handling errors in a type-safe environment
&lt;/h2&gt;

&lt;p&gt;In a typesafe environment, errors are more predictable, and handling them becomes more straightforward. Here are some examples of how you can handle errors when using Kysely with TypeScript:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Catching syntax errors at compile time:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With TypeScript, many syntax errors in your queries will be caught during compilation. For example, if you accidentally try to insert a string into a column that expects a number, TypeScript will flag this as an error.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="c1"&gt;// Assuming 'id' is a number&lt;/span&gt;&lt;br&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertInto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contacts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;not-a-number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;br&gt;
&lt;span class="c1"&gt;// TypeScript will flag an error here&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  &lt;strong&gt;Handling runtime errors:&lt;/strong&gt;&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;Despite the best efforts at compile time, some errors can only be caught at runtime (like database connectivity issues or unique constraint violations). You can handle these gracefully in your code.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertInto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contacts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&lt;a href="mailto:john@example.com"&gt;john@example.com&lt;/a&gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;An error occurred:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br&gt;
    &lt;span class="c1"&gt;// Additional error handling logic&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  &lt;strong&gt;Schema changes and refactoring:&lt;/strong&gt;&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;When you modify your database schema, TypeScript helps ensure changes are reflected throughout your code. If a column is removed or its type is changed, TypeScript will flag any incompatible queries.&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="c1"&gt;// If 'email' column is removed from the database schema&lt;/span&gt;&lt;br&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contacts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&lt;a href="mailto:new@email.com"&gt;new@email.com&lt;/a&gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;br&gt;
&lt;span class="c1"&gt;// TypeScript will flag an error if the 'email' column no longer exists&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Conclusion&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;In this tutorial, you created a typesafe Contact Management System using Kysely and Neon Postgres. Throughout the tutorial, you learned how to design and implement a database schema in a typesafe manner using Kysely, which allowed you to define your contacts table directly in TypeScript.&lt;/p&gt;

&lt;p&gt;The application's core functionality involved creating, reading, updating, and deleting contacts. You used Kysely's typesafe query builder to perform these tasks, which helped prevent many common errors associated with database interactions.&lt;/p&gt;

&lt;p&gt;The Contact Management System built in this tutorial serves as a foundational application, but it has the potential to be expanded and scaled. For example, integrating it with frontend frameworks and optimizing performance as the application grows might involve query optimization, database indexing, or leveraging caching mechanisms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/seveibar/kysely-neon/tree/main?utm_source=guides&amp;amp;utm_medium=content&amp;amp;utm_campaign=hackmamba" rel="noopener noreferrer"&gt;kysely-neon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kysely.dev/docs/category/examples?utm_source=hackmamba&amp;amp;utm_medium=blog&amp;amp;utm_id=HMBcommunity" rel="noopener noreferrer"&gt;kyesly examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://neon.tech/docs/introduction?ref=hm" rel="noopener noreferrer"&gt;Neon Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>neon</category>
      <category>postgressql</category>
      <category>database</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
