<?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: 100x.crypto 🚀🚀</title>
    <description>The latest articles on DEV Community by 100x.crypto 🚀🚀 (@walodja1987).</description>
    <link>https://dev.to/walodja1987</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%2F660805%2F01d21349-401c-4075-979f-6fdeb094039b.png</url>
      <title>DEV Community: 100x.crypto 🚀🚀</title>
      <link>https://dev.to/walodja1987</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/walodja1987"/>
    <language>en</language>
    <item>
      <title>Understanding TypeScript Execution Tools: A Deep Dive</title>
      <dc:creator>100x.crypto 🚀🚀</dc:creator>
      <pubDate>Fri, 05 Dec 2025 07:06:14 +0000</pubDate>
      <link>https://dev.to/walodja1987/understanding-typescript-execution-tools-a-deep-dive-14ca</link>
      <guid>https://dev.to/walodja1987/understanding-typescript-execution-tools-a-deep-dive-14ca</guid>
      <description>&lt;p&gt;When you start exploring TypeScript in Node.js, it's easy to get overwhelmed by all the tools, utilities, and concepts involved: &lt;code&gt;tsx&lt;/code&gt;, &lt;code&gt;ts-node&lt;/code&gt;, &lt;code&gt;tsc&lt;/code&gt;, &lt;code&gt;@types/node&lt;/code&gt;, &lt;code&gt;tsconfig.json&lt;/code&gt;, CommonJS, and ES Modules. It's not always obvious what each of these does or why they even exist.&lt;/p&gt;

&lt;p&gt;This blog post walks you through everything in a logical order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A brief history of JavaScript and its module system&lt;/li&gt;
&lt;li&gt;What Node.js is and how it handles modules&lt;/li&gt;
&lt;li&gt;What TypeScript is and how it compiles to JavaScript&lt;/li&gt;
&lt;li&gt;How to run TypeScript files using three different tools: &lt;code&gt;tsc&lt;/code&gt;, &lt;code&gt;ts-node&lt;/code&gt;, and &lt;code&gt;tsx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the end, you'll understand not only how to run &lt;code&gt;.ts&lt;/code&gt; files, but why things work the way they do and how to avoid the classic &lt;code&gt;Unexpected token 'export'&lt;/code&gt; errors.&lt;/p&gt;

&lt;p&gt;Let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. A Brief History of JavaScript
&lt;/h2&gt;

&lt;p&gt;JavaScript follows a language specification called &lt;strong&gt;ECMAScript&lt;/strong&gt;. Each version of ECMAScript (ES5, ES6, ES2020…) introduces new features to the JavaScript language. Below is a simplified overview of the major versions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ES3&lt;/td&gt;
&lt;td&gt;1999&lt;/td&gt;
&lt;td&gt;Very old, still the foundation of modern JavaScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ES5&lt;/td&gt;
&lt;td&gt;2009&lt;/td&gt;
&lt;td&gt;Big cleanup, added strict mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ES6 / ES2015&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2015&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Added classes, &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt;, and &lt;strong&gt;modules&lt;/strong&gt; (&lt;code&gt;import&lt;/code&gt;/&lt;code&gt;export&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ES2016–ES2023&lt;/td&gt;
&lt;td&gt;yearly&lt;/td&gt;
&lt;td&gt;Regular yearly updates with smaller language improvements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESNext&lt;/td&gt;
&lt;td&gt;future&lt;/td&gt;
&lt;td&gt;The next version; upcoming approved features not yet tied to a single release&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A &lt;em&gt;module&lt;/em&gt; in JavaScript is a separate file that exports values (functions, variables, classes) and can be imported by other files. Modules help you break your code into reusable, isolated pieces.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before ES6 (2015), JavaScript did not have a built-in module system. ES6 introduced native modules with the &lt;code&gt;import&lt;/code&gt; / &lt;code&gt;export&lt;/code&gt; syntax.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&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;import&lt;/span&gt; &lt;span class="nx"&gt;fs&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;fs&lt;/span&gt;&lt;span class="dl"&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;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example.txt&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;utf8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. What is Node.js
&lt;/h2&gt;

&lt;p&gt;Node.js (or "Node" in short) was created in 2009, years before ES6 existed. Node is a &lt;strong&gt;JavaScript runtime environment&lt;/strong&gt; which runs JavaScript outside the browser and provides additional functionality through APIs like &lt;code&gt;fs&lt;/code&gt;, &lt;code&gt;path&lt;/code&gt;, &lt;code&gt;crypto&lt;/code&gt;, etc. &lt;/p&gt;

&lt;p&gt;Because modules didn't exist yet, Node invented its own module system: &lt;strong&gt;CommonJS (CJS)&lt;/strong&gt;, which uses &lt;code&gt;require()&lt;/code&gt; and &lt;code&gt;module.exports&lt;/code&gt; syntax.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&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;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&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;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;example.txt&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;utf8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When ES6 modules arrived, Node could not support them immediately due to compatibility and ecosystem concerns. Years later, Node eventually added ESM support. But because millions of packages were already written in CommonJS and changing everything would break the ecosystem, Node decided to support both module systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Node decides which module system to use
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;type&lt;/code&gt; field in &lt;code&gt;package.json&lt;/code&gt; tells Node.js how to interpret &lt;code&gt;.js&lt;/code&gt; files: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When it's missing or &lt;code&gt;"type": "commonjs"&lt;/code&gt;, Node expects &lt;code&gt;require&lt;/code&gt; / &lt;code&gt;module.exports&lt;/code&gt; syntax in &lt;code&gt;.js&lt;/code&gt; files.&lt;/li&gt;
&lt;li&gt;When &lt;code&gt;"type": "module"&lt;/code&gt;, Node expects &lt;code&gt;import&lt;/code&gt; / &lt;code&gt;export&lt;/code&gt; syntax in &lt;code&gt;.js&lt;/code&gt; files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setting affects only how Node interprets &lt;code&gt;.js&lt;/code&gt; files, not how TypeScript compiles them (important to remember for later).&lt;/p&gt;




&lt;p&gt;Node's dual module support (CommonJS and ES Modules) is one of the main sources of confusion when using TypeScript in Node.js. But now that you understand the historical context, you're ready to learn how TypeScript fits into all of this and how it gets compiled to JavaScript. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. What is TypeScript
&lt;/h2&gt;

&lt;p&gt;TypeScript (TS) is a &lt;strong&gt;typed superset of JavaScript (JS)&lt;/strong&gt;. Let's break down what that really means.&lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript example
&lt;/h3&gt;

&lt;p&gt;In plain JavaScript, you might write a function like this:&lt;br&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;function&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Intuitively, the caller &lt;em&gt;should&lt;/em&gt; pass numbers, but nothing enforces that. Calling&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&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;b&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;…is perfectly valid JavaScript, and it will return:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;…because JavaScript will convert it to string concatenation.&lt;/p&gt;

&lt;h3&gt;
  
  
  How TypeScript improves this
&lt;/h3&gt;

&lt;p&gt;TypeScript adds &lt;strong&gt;optional static typing&lt;/strong&gt;, which lets you describe what types values &lt;em&gt;should&lt;/em&gt; have.&lt;/p&gt;

&lt;p&gt;The same function in TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&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;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We explicitly state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;a&lt;/code&gt; must be a number&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;b&lt;/code&gt; must be a number&lt;/li&gt;
&lt;li&gt;the function returns a number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&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;world&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;…TypeScript will give you a compile-time error, before the code runs. &lt;strong&gt;Catching mistakes without executing your code is one of the main benefits of TypeScript.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Type annotations in your code
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;type annotations in your code are optional&lt;/strong&gt;, meaning that you can add types but you don't have to. That is, you can write plain JavaScript inside a &lt;code&gt;.ts&lt;/code&gt; file and TypeScript will still compile it. &lt;/p&gt;

&lt;p&gt;If you omit types, TypeScript will try to infer them (e.g., &lt;code&gt;const x = 5&lt;/code&gt; becomes a &lt;code&gt;number&lt;/code&gt;), and if it cannot infer a type, it falls back to the &lt;code&gt;any&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;This allows you to adopt TypeScript's type system gradually at your own pace.&lt;/p&gt;

&lt;h3&gt;
  
  
  Type definitions for the runtime environment
&lt;/h3&gt;

&lt;p&gt;To analyze your code, TypeScript must not only understand the types in the code you write, but also the &lt;strong&gt;types of the APIs provided by the runtime environment&lt;/strong&gt; (e.g., browser DOM APIs or Node's built-in modules).&lt;/p&gt;

&lt;p&gt;There are two environments you'll most commonly use with TypeScript:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Browser environment:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you install TypeScript, it automatically includes DOM type definitions. These describe the APIs that browsers provide (e.g., &lt;code&gt;window&lt;/code&gt;, &lt;code&gt;document&lt;/code&gt;, &lt;code&gt;fetch&lt;/code&gt;, &lt;code&gt;setTimeout&lt;/code&gt;). TypeScript bundles their type definitions by default because many TypeScript projects are browser-based.&lt;/p&gt;

&lt;p&gt;➡️ &lt;strong&gt;You don't need to install anything extra.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Node environment:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Node provides its own APIs that do &lt;em&gt;not&lt;/em&gt; exist in JavaScript or the browser (e.g., &lt;code&gt;fs&lt;/code&gt;, &lt;code&gt;path&lt;/code&gt;, &lt;code&gt;process&lt;/code&gt;). TypeScript does &lt;strong&gt;not&lt;/strong&gt; bundle type defintions for Node by default. &lt;/p&gt;

&lt;p&gt;So if you want to use Node APIs in TypeScript (e.g., &lt;code&gt;import fs from "fs"&lt;/code&gt;), you must install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; @types/node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without this package, TypeScript will complain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cannot find module 'fs'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;➡️ &lt;strong&gt;Whenever you write TypeScript for Node.js and use Node APIs, you need to install &lt;code&gt;@types/node&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Compilation of TypeScript to JavaScript
&lt;/h3&gt;

&lt;p&gt;Browsers and Node.js &lt;strong&gt;cannot run TypeScript directly&lt;/strong&gt;, they only understand JavaScript. Therefore, TypeScript must be translated ("compiled" / "transpiled") to JavaScript. To do that you need tools like &lt;code&gt;tsc&lt;/code&gt;, &lt;code&gt;ts-node&lt;/code&gt; or &lt;code&gt;tsx&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;These tools "strip out" the TypeScript types and produce valid JavaScript that Node.js or browsers can execute.&lt;/p&gt;

&lt;h3&gt;
  
  
  How TypeScript decides what JavaScript to emit
&lt;/h3&gt;

&lt;p&gt;TypeScript uses a configuration file called &lt;code&gt;tsconfig.json&lt;/code&gt;, located/created in the root of your project, which tells TypeScript how to compile &lt;code&gt;.ts&lt;/code&gt; files into &lt;code&gt;.js&lt;/code&gt; files.&lt;/p&gt;

&lt;p&gt;The two most important settings are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;compilerOptions.target&lt;/code&gt;: Defines &lt;strong&gt;which version of JavaScript&lt;/strong&gt; TypeScript should generate (e.g., &lt;code&gt;ES5&lt;/code&gt;, &lt;code&gt;ES2015&lt;/code&gt;, &lt;code&gt;ES2020&lt;/code&gt;, etc.; see the history table above for all available options).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;compilerOptions.module&lt;/code&gt;: Defines &lt;strong&gt;which module system&lt;/strong&gt; the emitted JavaScript should use.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"commonjs"&lt;/code&gt; → output uses &lt;code&gt;require&lt;/code&gt; / &lt;code&gt;module.export&lt;/code&gt; syntax&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"es2015"&lt;/code&gt; / &lt;code&gt;"es2020"&lt;/code&gt; / &lt;code&gt;"esnext"&lt;/code&gt; → output uses &lt;code&gt;import&lt;/code&gt; / &lt;code&gt;export&lt;/code&gt; syntax&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Example &lt;code&gt;tsconfig.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES2020"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commonjs"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells TypeScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Compile my code to JavaScript that matches ES2020 features"&lt;/li&gt;
&lt;li&gt;"Use CommonJS module syntax in the output"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If no &lt;code&gt;tsconfig.json&lt;/code&gt; file is provided, TypeScipt defaults to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commonjs"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Puuh... that was a lot of background, but it's all essential context. With this foundation in place, we can now explore the different tools for compiling and running TypeScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Setup an example project
&lt;/h2&gt;

&lt;p&gt;Let's create a fresh project with a simple TypeScript file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-typescript-project
&lt;span class="nb"&gt;cd &lt;/span&gt;my-typescript-project
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create &lt;strong&gt;hello.ts&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;join&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;path&lt;/span&gt;&lt;span class="dl"&gt;"&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="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;folder&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;file.txt&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 uses ESM. But since &lt;code&gt;package.json&lt;/code&gt; has &lt;strong&gt;no&lt;/strong&gt; &lt;code&gt;"type": "module"&lt;/code&gt;, Node expects &lt;strong&gt;CommonJS&lt;/strong&gt;, which creates a mismatch and is expected to result in an error.&lt;/p&gt;

&lt;p&gt;Let's see how we can use &lt;code&gt;tsc&lt;/code&gt;, &lt;code&gt;ts-node&lt;/code&gt; and &lt;code&gt;tsx&lt;/code&gt; to execute the scripts and how each of them addresses the mismatch.&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Executing TypeScript with &lt;code&gt;tsc&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;tsc&lt;/code&gt; is the official TypeScript compiler. It converts TypeScript into JavaScript so Node.js can run it. &lt;/p&gt;

&lt;p&gt;Workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hello.ts
    ↓
tsc compiles it to hello.js
    ↓
node runs hello.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installation and configuration
&lt;/h2&gt;

&lt;p&gt;To use &lt;code&gt;tsc&lt;/code&gt;, first install TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, generate a &lt;code&gt;tsconfig.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tsc &lt;span class="nt"&gt;--init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: While &lt;code&gt;tsc&lt;/code&gt; can compile files without configuration, it's best practice to use a &lt;code&gt;tsconfig.json&lt;/code&gt; file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This creates a configuration file with recommended settings, as shown below (comments and unused options were removed for clarity):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es2016"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commonjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"esModuleInterop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"forceConsistentCasingInFileNames"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"skipLibCheck"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have already discussed &lt;code&gt;target&lt;/code&gt; and &lt;code&gt;module&lt;/code&gt;. Here is a brief explanation of the other options:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;esModuleInterop: true&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Allows importing CommonJS modules (i.e., files using &lt;code&gt;require&lt;/code&gt; / &lt;code&gt;module.exports&lt;/code&gt; syntax) into ES modules (i.e., files using &lt;code&gt;import&lt;/code&gt; / &lt;code&gt;export&lt;/code&gt; syntax).&lt;/p&gt;

&lt;p&gt;Without it, you'd need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&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;With it, you can simply write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&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 enables interoperability between CommonJS and ES packages.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;forceConsistentCasingInFileNames: true&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Enforces consistent casing in import paths to prevent issues on case-sensitive file systems. This prevents bugs where &lt;code&gt;./MyFile&lt;/code&gt; and &lt;code&gt;./myfile&lt;/code&gt; would be treated differently.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;strict: true&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Enables all strict type-checking options for better type safety. It catches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;implicity &lt;code&gt;any&lt;/code&gt; types&lt;/li&gt;
&lt;li&gt;null/undefined issues&lt;/li&gt;
&lt;li&gt;incorrect argument types&lt;/li&gt;
&lt;li&gt;uninitialized class properties&lt;/li&gt;
&lt;li&gt;and more. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the setting that gives TypeScript its reputation for safety.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;skipLibCheck: true&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Skips type checking of declaration files (&lt;code&gt;.d.ts&lt;/code&gt;) in &lt;code&gt;node_modules&lt;/code&gt; to speed up compilation. Your code is still fully type-checked; only third-party library types are skipped.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compilation
&lt;/h2&gt;

&lt;p&gt;To compile your project, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tsc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates a &lt;code&gt;.js&lt;/code&gt; file for each &lt;code&gt;.ts&lt;/code&gt; file in your project (in our case, &lt;code&gt;hello.js&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;If you inspect &lt;code&gt;hello.js&lt;/code&gt;, you will find the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;__esModule&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="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;path_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;path_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;folder&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;file.txt&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;You see the &lt;code&gt;require()&lt;/code&gt; syntax because &lt;code&gt;module: "commonjs"&lt;/code&gt; was set in &lt;code&gt;tsconfig.json&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run with Node
&lt;/h2&gt;

&lt;p&gt;Now you can run &lt;code&gt;hello.js&lt;/code&gt; with Node (note that it's &lt;code&gt;.js&lt;/code&gt;, not &lt;code&gt;.ts&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node hello.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Notes on compiling single files
&lt;/h2&gt;

&lt;p&gt;When you specify file names after &lt;code&gt;tsc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tsc hello.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you're invoking &lt;code&gt;tsc&lt;/code&gt; in &lt;strong&gt;single-file mode&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In this mode, TypeScript ignores &lt;code&gt;tsconfig.json&lt;/code&gt; and compiles the specified file(s) with it's built-in defaults (i.e. &lt;code&gt;target: "es3"&lt;/code&gt; and &lt;code&gt;module: "commonjs"&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;Try it out yourself: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;module: "es2020"&lt;/code&gt; in  &lt;code&gt;tsconfig.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npx tsc hello.ts&lt;/code&gt; -&amp;gt; You still get CommonJS syntax in the output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only if you run &lt;code&gt;npx tsc&lt;/code&gt; without file names, it will use the configuration specified in your &lt;code&gt;tsconfig.json&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Below the commands to install and execute TypeScript with &lt;code&gt;tsc&lt;/code&gt; for quick reference (including installation of &lt;code&gt;@types/node&lt;/code&gt; for completeness):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;save&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;dev&lt;/span&gt; &lt;span class="nx"&gt;typescript&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;types&lt;/span&gt;&lt;span class="sr"&gt;/nod&lt;/span&gt;&lt;span class="err"&gt;e
&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;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;tsc&lt;/span&gt;
&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Replace &lt;code&gt;file.js&lt;/code&gt; with the name of your file)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Further reading:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/tsconfig-json.html" rel="noopener noreferrer"&gt;https://www.typescriptlang.org/docs/handbook/tsconfig-json.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  6. Executing TypeScript using &lt;code&gt;ts-node&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;ts-node&lt;/code&gt; is a tool that allows you to run TypeScript files &lt;strong&gt;directly&lt;/strong&gt;, without generating &lt;code&gt;.js&lt;/code&gt; files. It transpiles your &lt;code&gt;.ts&lt;/code&gt; code in memory and executes it immediately.&lt;/p&gt;

&lt;p&gt;Workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hello.ts
    ↓
ts-node transpiles &amp;amp; executes in memory (no .js files are created)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ts-node&lt;/code&gt; is great for development, quick scripts, and interactive use. It &lt;strong&gt;always&lt;/strong&gt; respects your &lt;code&gt;tsconfig.json&lt;/code&gt;. There are no special cases like in &lt;code&gt;tsc&lt;/code&gt; where it may be ignored.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation and requirements
&lt;/h2&gt;

&lt;p&gt;To use &lt;code&gt;ts-node&lt;/code&gt;, install both &lt;strong&gt;ts-node&lt;/strong&gt; and &lt;strong&gt;typescript&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; ts-node typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: &lt;code&gt;ts-node&lt;/code&gt; &lt;em&gt;does not include&lt;/em&gt; TypeScript.&lt;br&gt;
It is just a &lt;em&gt;wrapper&lt;/em&gt; that asks the TypeScript compiler to transpile your file in memory.&lt;br&gt;
Without installing &lt;code&gt;typescript&lt;/code&gt;, &lt;code&gt;ts-node&lt;/code&gt; will throw:&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: Cannot find module 'typescript'
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Running TypeScript with &lt;code&gt;ts-node&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Once installed, run your TypeScript file directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ts-node hello.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reads your &lt;strong&gt;tsconfig.json&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Transpiles the file in memory&lt;/li&gt;
&lt;li&gt;Executes it immediately&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No &lt;code&gt;.js&lt;/code&gt; file is created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Below the commands to install and execute TypeScript with &lt;code&gt;ts-node&lt;/code&gt; for quick reference (including installation of &lt;code&gt;@types/node&lt;/code&gt; for completeness):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;save&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;dev&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;typescript&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;types&lt;/span&gt;&lt;span class="sr"&gt;/nod&lt;/span&gt;&lt;span class="err"&gt;e
&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;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;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Replace &lt;code&gt;file.js&lt;/code&gt; with the name of your file)&lt;/p&gt;

&lt;h1&gt;
  
  
  7. Executing TypeScript using &lt;code&gt;tsx&lt;/code&gt; (Easiest Option)
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;tsx&lt;/code&gt; is the &lt;strong&gt;simplest and most modern&lt;/strong&gt; way to run TypeScript files.&lt;br&gt;
It runs &lt;code&gt;.ts&lt;/code&gt; files &lt;strong&gt;directly&lt;/strong&gt;, without creating &lt;code&gt;.js&lt;/code&gt; files, and requires &lt;strong&gt;zero configuration&lt;/strong&gt; in most cases.&lt;/p&gt;

&lt;p&gt;Workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hello.ts
    ↓
tsx transpiles &amp;amp; executes in memory (no .js files are created)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key difference compared to &lt;code&gt;ts-node&lt;/code&gt; is that &lt;code&gt;tsx&lt;/code&gt; handles many cross-environment details automatically. It works out of the box with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ES Modules and CommonJS&lt;/li&gt;
&lt;li&gt;JSX / TSX&lt;/li&gt;
&lt;li&gt;TypeScript path aliases&lt;/li&gt;
&lt;li&gt;JSON imports&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.mjs&lt;/code&gt;, &lt;code&gt;.cjs&lt;/code&gt;, &lt;code&gt;.ts&lt;/code&gt;, &lt;code&gt;.tsx&lt;/code&gt;, &lt;code&gt;.jsx&lt;/code&gt;, &lt;code&gt;.js&lt;/code&gt; files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…and requires almost &lt;strong&gt;no setup&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;First, install &lt;code&gt;tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike &lt;code&gt;ts-node&lt;/code&gt;, &lt;code&gt;tsx&lt;/code&gt; already bundles everything it needs to execute TS files. It does &lt;strong&gt;not&lt;/strong&gt; require installing &lt;code&gt;typescript&lt;/code&gt; separately, though most projects will have &lt;code&gt;typescript&lt;/code&gt; installed anyway.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you already installed TypeScript or &lt;code&gt;ts-node&lt;/code&gt; earlier, uninstall them or start a fresh project so you can clearly see that &lt;code&gt;tsx&lt;/code&gt; works without any additional setup.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Running TypeScript with &lt;code&gt;tsx&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Simply run your TypeScript file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tsx hello.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No &lt;code&gt;tsconfig.json&lt;/code&gt; required. No &lt;code&gt;.js&lt;/code&gt; output. No module-system headaches.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tsx&lt;/code&gt; automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detects whether your project uses &lt;code&gt;"type": "module"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Handles CommonJS and ESM differences&lt;/li&gt;
&lt;li&gt;Applies sensible defaults&lt;/li&gt;
&lt;li&gt;Loads TypeScript configuration if it exists&lt;/li&gt;
&lt;li&gt;Avoids the &lt;code&gt;Unexpected token 'export'&lt;/code&gt; errors that beginners often hit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It just works.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; &lt;code&gt;tsx&lt;/code&gt; also provides a watch mode for development:&lt;/p&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tsx watch hello.ts
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This automatically reruns your script whenever the file changes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;For quick reference:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; tsx @types/node
npx tsx file.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Replace &lt;code&gt;file.ts&lt;/code&gt; with the TypeScript file you want to run.)&lt;/p&gt;

&lt;p&gt;Absolutely — here is a polished and clear section &lt;strong&gt;“When to Use What”&lt;/strong&gt;, matching the tone and structure of your existing sections.&lt;/p&gt;

&lt;h1&gt;
  
  
  8. When to Use What (&lt;code&gt;tsc&lt;/code&gt; vs &lt;code&gt;ts-node&lt;/code&gt; vs &lt;code&gt;tsx&lt;/code&gt;)
&lt;/h1&gt;

&lt;p&gt;You now know three different ways to run TypeScript:&lt;br&gt;
&lt;code&gt;tsc&lt;/code&gt;, &lt;code&gt;ts-node&lt;/code&gt;, and &lt;code&gt;tsx&lt;/code&gt;.&lt;br&gt;
But which one should you actually use?&lt;/p&gt;

&lt;p&gt;This section gives you a simple, practical decision guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Use &lt;strong&gt;&lt;code&gt;tsx&lt;/code&gt;&lt;/strong&gt; when you want the &lt;strong&gt;easiest, fastest developer experience&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;tsx&lt;/code&gt; is ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;small scripts&lt;/li&gt;
&lt;li&gt;development environments&lt;/li&gt;
&lt;li&gt;experimentation / prototyping&lt;/li&gt;
&lt;li&gt;running files directly&lt;/li&gt;
&lt;li&gt;building CLIs or dev tools&lt;/li&gt;
&lt;li&gt;any situation where you &lt;strong&gt;don’t care about emitted &lt;code&gt;.js&lt;/code&gt; files&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero config&lt;/li&gt;
&lt;li&gt;Just works with ESM and CJS&lt;/li&gt;
&lt;li&gt;Bundles everything it needs&lt;/li&gt;
&lt;li&gt;Fastest startup&lt;/li&gt;
&lt;li&gt;No &lt;code&gt;.js&lt;/code&gt; output clutter&lt;/li&gt;
&lt;li&gt;Great watch mode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not a build tool&lt;/li&gt;
&lt;li&gt;Not ideal for production deployment (since nothing is emitted)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Recommendation:&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;tsx&lt;/code&gt; for &lt;strong&gt;99% of development&lt;/strong&gt; and daily scripting.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Use &lt;strong&gt;&lt;code&gt;ts-node&lt;/code&gt;&lt;/strong&gt; when you need &lt;strong&gt;TypeScript execution that respects your project configuration&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ts-node&lt;/code&gt; is ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;long-running dev environments&lt;/li&gt;
&lt;li&gt;debugging complex TS applications&lt;/li&gt;
&lt;li&gt;environments that rely heavily on your TypeScript configuration&lt;/li&gt;
&lt;li&gt;older projects that already use &lt;code&gt;ts-node&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;scripts/workflows integrated into existing tooling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always respects &lt;code&gt;tsconfig.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;No &lt;code&gt;.js&lt;/code&gt; files emitted&lt;/li&gt;
&lt;li&gt;Supports advanced TS features&lt;/li&gt;
&lt;li&gt;Embedded in many mature TS ecosystems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slower startup than &lt;code&gt;tsx&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Requires installing &lt;code&gt;typescript&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;More sensitive to ESM/CJS configuration&lt;/li&gt;
&lt;li&gt;Requires more setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Recommendation:&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;ts-node&lt;/code&gt; when you have a &lt;strong&gt;configured TypeScript project&lt;/strong&gt; and need the compiler settings to be honored exactly.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Use &lt;strong&gt;&lt;code&gt;tsc&lt;/code&gt;&lt;/strong&gt; when you need &lt;strong&gt;actual &lt;code&gt;.js&lt;/code&gt; output&lt;/strong&gt; (production builds)
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;tsc&lt;/code&gt; is ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;production deployments&lt;/li&gt;
&lt;li&gt;packaging libraries&lt;/li&gt;
&lt;li&gt;creating build artifacts&lt;/li&gt;
&lt;li&gt;publishing to npm&lt;/li&gt;
&lt;li&gt;bundling workflows (paired with tools like esbuild, webpack, tsup, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Produces clean &lt;code&gt;.js&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;Lets Node run without any TS tooling&lt;/li&gt;
&lt;li&gt;Uses static analysis to catch errors before runtime&lt;/li&gt;
&lt;li&gt;Needed for code that must run in production environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requires a config&lt;/li&gt;
&lt;li&gt;Two-step workflow: compile → execute&lt;/li&gt;
&lt;li&gt;Can be slow without incremental builds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Recommendation:&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;tsc&lt;/code&gt; for &lt;strong&gt;build steps&lt;/strong&gt;, production bundles, and anything you want to &lt;strong&gt;ship or deploy&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  9. Final words
&lt;/h1&gt;

&lt;p&gt;We covered a lot of ground, from JavaScript history, to module systems, to TypeScript configuration, all the way to three different execution tools. With this foundation in place, you're well-positioned to explore more advanced TypeScript features and deepen your understanding at your own pace.&lt;/p&gt;

</description>
      <category>typescript</category>
    </item>
    <item>
      <title>Run TypeScript Files in 30 Seconds</title>
      <dc:creator>100x.crypto 🚀🚀</dc:creator>
      <pubDate>Sun, 23 Nov 2025 16:13:08 +0000</pubDate>
      <link>https://dev.to/walodja1987/run-typescript-files-in-30-seconds-4b3l</link>
      <guid>https://dev.to/walodja1987/run-typescript-files-in-30-seconds-4b3l</guid>
      <description>&lt;p&gt;If you have a TypeScript script (&lt;code&gt;.ts&lt;/code&gt; file) and want to run it quickly without setting up a full build pipeline or compiling anything manually, this guide shows you how to run it in 30 seconds.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Environment:&lt;/strong&gt; I'm using WSL (Ubuntu) on Windows, but this works the same on Linux and macOS. I also assume you already have &lt;a href="https://nodejs.org/en/download" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; installed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 1: Create a New Project Directory
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-typescript-project
&lt;span class="nb"&gt;cd &lt;/span&gt;my-typescript-project
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Install tsx
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;tsx&lt;/code&gt; runs TypeScript files directly without compiling to JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Run Your TypeScript File
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tsx your-file.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let's look at a practical example. Suppose you have a JSON file exported from a Discord chat and want to convert it to Markdown.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;data.json:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"thread_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"thread_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Example Thread"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"messages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"message_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"author_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-01-15T10:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"attachments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"message_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"author_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-01-15T10:05:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Hi there!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"attachments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;convert-to-markdown.ts:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&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="nx"&gt;data&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./data.json&lt;/span&gt;&lt;span class="dl"&gt;'&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;Message&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;message_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;author_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;attachments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[];&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;Thread&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;thread_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;message_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Message&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;threads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;markdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;# Threads&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;markdown&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`## &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;thread_name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n\n`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;markdown&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`### &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author_name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; - &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n\n`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;markdown&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n\n`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;markdown&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;---&lt;/span&gt;&lt;span class="se"&gt;\n\n&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="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output.md&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;markdown&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Converted to output.md&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;Set up a project directory as described earlier and place both files inside it.&lt;/p&gt;

&lt;p&gt;Then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx tsx convert-to-markdown.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;output.md&lt;/code&gt; is created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick reference
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1) Setup&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-typescript-project
&lt;span class="nb"&gt;cd &lt;/span&gt;my-typescript-project
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; tsx

&lt;span class="c"&gt;# 2) Add the .ts file into the directory&lt;/span&gt;

&lt;span class="c"&gt;# 3) Run&lt;/span&gt;
npx tsx your-file.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>typescript</category>
    </item>
    <item>
      <title>Symlinks</title>
      <dc:creator>100x.crypto 🚀🚀</dc:creator>
      <pubDate>Sun, 02 Nov 2025 18:59:08 +0000</pubDate>
      <link>https://dev.to/walodja1987/symlinks-2gjh</link>
      <guid>https://dev.to/walodja1987/symlinks-2gjh</guid>
      <description>&lt;h2&gt;
  
  
  🧩 Intro
&lt;/h2&gt;

&lt;p&gt;In my previous blog post on &lt;a href="https://dev.to/walodja1987/how-to-back-up-and-sync-your-terminal-configuration-with-a-github-dotfiles-repo-4p17"&gt;how to back up and sync your terminal configuration with a GitHub dotfiles repo&lt;/a&gt;, we had to manually copy configuration files into the &lt;code&gt;~/dotfiles&lt;/code&gt; directory every time we wanted to push updates to GitHub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; ~/.bashrc ~/dotfiles/bashrc
&lt;span class="nb"&gt;cp&lt;/span&gt; ~/.bash_aliases ~/dotfiles/bash_aliases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you changed &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.bash_aliases&lt;/code&gt;, you had to remember to copy them back into &lt;code&gt;~/dotfiles&lt;/code&gt; before committing.&lt;/p&gt;

&lt;p&gt;That’s tedious and easy to forget. What if the files stayed in sync automatically? That’s where symlinks come in handy.&lt;/p&gt;

&lt;h2&gt;
  
  
  🪄 What is a symlink?
&lt;/h2&gt;

&lt;p&gt;A symlink (short for &lt;em&gt;symbolic link&lt;/em&gt;) is like a shortcut or reference to another file or folder. It points to the original location and behaves like the real file, meaning you can open, read, or edit it just like the original. If you’ve ever created shortcuts on Windows, it’s the same concept.&lt;/p&gt;

&lt;p&gt;Think of it like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📁 &lt;strong&gt;Original file:&lt;/strong&gt; &lt;code&gt;~/.bashrc&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;📎 &lt;strong&gt;Symlink:&lt;/strong&gt; &lt;code&gt;~/dotfiles/bashrc&lt;/code&gt; → points to that original file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a program or shell tries to read &lt;code&gt;~/dotfiles/bashrc&lt;/code&gt;, the system redirects it to the real file &lt;code&gt;~/.bashrc&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Syntax
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &amp;lt;original&amp;gt; &amp;lt;&lt;span class="nb"&gt;link&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Where:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;original&amp;gt;&lt;/code&gt;: the &lt;strong&gt;original file&lt;/strong&gt; or directory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;: the &lt;strong&gt;new symlink&lt;/strong&gt; (the name/path of the shortcut you want to create)&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;-s&lt;/code&gt; flag stands for symbolic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; ~/.bashrc ~/dotfiles/bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This creates &lt;code&gt;~/dotfiles/bashrc&lt;/code&gt; as a shortcut to &lt;code&gt;~/.bashrc&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When you edit &lt;code&gt;~/.bashrc&lt;/code&gt;, the change is immediately reflected in &lt;code&gt;~/dotfiles/bashrc&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When you edit &lt;code&gt;~/dotfiles/bashrc&lt;/code&gt;, the change is immediately reflected in &lt;code&gt;~/.bashrc&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You can commit and push &lt;code&gt;~/dotfiles/bashrc&lt;/code&gt; to GitHub without manual copying.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📌 Quick symlink cheatsheet
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ln -s &amp;lt;original&amp;gt; &amp;lt;link&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a symbolic link&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ls -l&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show links to the original&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rm &amp;lt;link&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete only the symlink (not the original file)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;readlink &amp;lt;link&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show where the symlink points&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  💡 Things to keep in mind
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name collisions:&lt;/strong&gt; If &lt;code&gt;~/dotfiles/bashrc&lt;/code&gt; already exists, the &lt;code&gt;ln -s&lt;/code&gt; command will fail. Delete or rename the existing file first via
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; ~/dotfiles/bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deleting the symlink&lt;/strong&gt; does not delete the original file; it just removes the shortcut.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deleting or moving the original file&lt;/strong&gt; will &lt;strong&gt;break the symlink&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If the original file has been deleted, editing the symlink may either create a new file at the path it points to or throw an error (depending on your editor). So, as long as the original exists, both stay perfectly in sync.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File permissions and metadata:&lt;/strong&gt;
A symlink has its own minimal permissions (&lt;code&gt;lrwxrwxrwx&lt;/code&gt;), which don’t affect the original.
Running &lt;code&gt;ls -l&lt;/code&gt; shows the link’s metadata, not the original’s.
Use &lt;code&gt;ls -lL&lt;/code&gt; to view the original’s details.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relative vs. absolute paths:&lt;/strong&gt;
A symlink stores the &lt;em&gt;path string&lt;/em&gt; to its target, either &lt;strong&gt;absolute&lt;/strong&gt; (e.g., &lt;code&gt;/home/user/.bashrc&lt;/code&gt;) or &lt;strong&gt;relative&lt;/strong&gt; (e.g., &lt;code&gt;../.bashrc&lt;/code&gt;).

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Absolute symlinks&lt;/strong&gt; contain the full path. They work as long as the original stays in the same place, but will break if the file is moved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relative symlinks&lt;/strong&gt; use a path relative to the link’s own location. These are more portable. If you move the whole directory structure (e.g., a Git repo or project folder), the links still work because the relative relationship remains the same.
You can create a relative symlink like this:
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; ../real_folder shortcut
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Symlinks can point to &lt;strong&gt;directories&lt;/strong&gt; as well as files.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✨ Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Symlinks are a simple yet powerful way to automate your dotfiles workflow.&lt;br&gt;
They remove the need for manual copies and keep your configurations perfectly in sync across devices.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: I use ChatGPT to help me gather information and shape these posts, but I always test the commands myself and add my own insights to make them easier to understand. This blog is my personal record of what I learn as I go deeper into Linux. If it helps someone else too, even better!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cli</category>
      <category>linux</category>
      <category>beginners</category>
      <category>automation</category>
    </item>
    <item>
      <title>How to install Git on Ubuntu and push your first repository to GitHub</title>
      <dc:creator>100x.crypto 🚀🚀</dc:creator>
      <pubDate>Fri, 17 Oct 2025 15:22:29 +0000</pubDate>
      <link>https://dev.to/walodja1987/how-to-install-git-on-ubuntu-and-push-your-first-repository-to-github-21gl</link>
      <guid>https://dev.to/walodja1987/how-to-install-git-on-ubuntu-and-push-your-first-repository-to-github-21gl</guid>
      <description>&lt;p&gt;Git is the most widely used version control system in the world. If you're building software, writing scripts, or even just managing configuration files, it's an essential tool to learn.&lt;/p&gt;

&lt;p&gt;In this guide, we'll walk step-by-step through:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;🛠️ Installing Git on Ubuntu&lt;/li&gt;
&lt;li&gt;✏️ Configuring your Git identity&lt;/li&gt;
&lt;li&gt;📁 Creating a local repository&lt;/li&gt;
&lt;li&gt;🔑 Setting up SSH access to GitHub&lt;/li&gt;
&lt;li&gt;🌐 Connecting it to GitHub&lt;/li&gt;
&lt;li&gt;🚀 Pushing your first commit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prerequisite:&lt;/strong&gt; You'll need a &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub account&lt;/a&gt; before starting. If you don't have one yet, sign up. It's free and takes just a minute.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ Step 1: Install Git on Ubuntu
&lt;/h2&gt;

&lt;p&gt;Check if Git is already installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see &lt;code&gt;command not found&lt;/code&gt;, continue with the installation steps below. If it's already installed, move on to Step 2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;git &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;-y&lt;/code&gt; flag "yes" automatically answers "yes" to any prompts during the installation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Verify the installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If successful, it should return something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git version 2.34.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✏️ Step 2: Configure your Git identity
&lt;/h2&gt;

&lt;p&gt;Git needs to know your name and email so it can label your commits. You'll see them locally in &lt;code&gt;git log&lt;/code&gt; and on GitHub next to each commit. &lt;/p&gt;

&lt;p&gt;To set your name and email run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &lt;span class="s2"&gt;"your-email@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;user.name&lt;/code&gt; does not have to match your GitHub username. It's just a label on your commits. Use your real name or a handle, up to you.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;user.email&lt;/code&gt; should match one of the emails registered with your GitHub account if you want your commits linked to your profile. If it doesn't, commits still appear, but won't show your avatar or count toward your contribution graph.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Verify your settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; &lt;span class="nt"&gt;--list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user.name=Your Name
user.email=your-email@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔑 Step 3: Set up SSH access to GitHub
&lt;/h2&gt;

&lt;p&gt;Using SSH means you won't have to type your username and password every time you push code to GitHub.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1. Check existing SSH keys
&lt;/h3&gt;

&lt;p&gt;Let's first check whether you have existing SSH keys.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; ~/.ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see files like &lt;code&gt;id_ed25519&lt;/code&gt; and &lt;code&gt;id_ed25519.pub&lt;/code&gt;, you already have a key pair and you can continue with Step 4.&lt;/p&gt;

&lt;p&gt;If you don't have any or wish to create new ones, continue with this step.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2. Generate a new SSH key
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;📌 &lt;strong&gt;Warning:&lt;/strong&gt; If you generate a new key with the same name as an existing one, you will overwrite it and any service (like GitHub) using the old key will stop recognizing your machine until you add the new one. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Generate an SSH key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"test-key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-t&lt;/code&gt; defines the key type which is &lt;code&gt;ed25519&lt;/code&gt; in our case.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-C&lt;/code&gt; adds a comment to your SSH key. It's just a label to help identify the key later if you generate multiple ones. It's not used for authentication or commit association.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;You'll be asked to enter a name for the new key. If you simply press &lt;code&gt;Enter&lt;/code&gt;, the key will be saved under the default name &lt;code&gt;id_ed255119&lt;/code&gt;. To avoid overwriting any existing keys, append the proposed name with &lt;code&gt;_test&lt;/code&gt;. Make sure to include the full path and replace &lt;code&gt;walodja1987&lt;/code&gt; with &lt;em&gt;your&lt;/em&gt; Ubuntu username:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/home/walodja1987/.ssh/id_ed25519_test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll be asked to set a password to protect your keys. It's optional but recommended.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3. Start the SSH agent and add your key
&lt;/h3&gt;

&lt;p&gt;Before we run the commands, let's briefly understand &lt;strong&gt;what an SSH agent is&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you generated the key with &lt;code&gt;ssh-keygen&lt;/code&gt;, it was saved as a file on your disk (&lt;code&gt;/home/walodja1987/.ssh/id_ed25519_test&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;That file contains your private key, but SSH clients like Git won't use it automatically. And if it's protected by a passphrase, they can't read it directly without your help.&lt;/li&gt;
&lt;li&gt;An SSH agent is a small background program that runs in your session and remembers unlocked keys in RAM. It handles authentication automatically any time you connect to a server like GitHub over SSH, without asking you to type the passphrase again.&lt;/li&gt;
&lt;li&gt;Think of &lt;code&gt;ssh-keygen&lt;/code&gt; as &lt;em&gt;creating a key&lt;/em&gt; and storing it in a safe. &lt;code&gt;ssh-add&lt;/code&gt; is like &lt;em&gt;unlocking it once and handing it to a trusted assistant (the SSH agent)&lt;/em&gt;, who will present it whenever needed, so you don't have to fetch and unlock it yourself each time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With that in mind, let's start the SSH agent and add your key. 👇&lt;/p&gt;

&lt;p&gt;First, check that SSH tools are installed (they usually are on Ubuntu, but minimal Docker images not include them):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-V&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't see an OpenSSH version in the output, install the client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; openssh-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now start the SSH agent and add your key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ssh-agent &lt;span class="nt"&gt;-s&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
ssh-add ~/.ssh/id_ed25519_test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what's happening:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;eval "$(ssh-agent -s)"&lt;/code&gt;: Starts the SSH agent and sets up your environment to talk to it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ssh-add ~/.ssh/id_ed25519_test&lt;/code&gt;: Loads your private key into the agent. If it's passphrase-protected, you'll be prompted once. After that, the agent remembers it for the rest of your session.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can confirm the key was added with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-add &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.4. Add your public key to GitHub
&lt;/h3&gt;

&lt;p&gt;Show your public key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_ed25519_test.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the full line (it starts with &lt;code&gt;ssh-ed25519&lt;/code&gt; and ends with the comment you chose, e.g. &lt;code&gt;test-key&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Then go to &lt;strong&gt;GitHub → Settings → SSH and GPG keys → New SSH key&lt;/strong&gt;, then paste it there.&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%2F7u4w3utquf5o896s05oc.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%2F7u4w3utquf5o896s05oc.png" alt=" " width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3.5. Test the SSH connection
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-T&lt;/span&gt; git@github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything is set up correctly, you'll see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hi &amp;lt;your-username&amp;gt;! You've successfully authenticated, but GitHub does not provide shell access.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The first time you run this command, you may see &lt;code&gt;The authenticity of host 'github.com (140.82.121.4)' can't be established&lt;/code&gt;. Just confirm with &lt;code&gt;yes&lt;/code&gt; to continue.&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%2F9tc9mcinqw73ojtb8avx.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%2F9tc9mcinqw73ojtb8avx.png" alt=" " width="800" height="117"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📁 Step 4: Create a new repository on GitHub
&lt;/h2&gt;

&lt;p&gt;Go to &lt;a href="https://github.com/new" rel="noopener noreferrer"&gt;https://github.com/new&lt;/a&gt; and create a new repository.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose a name (e.g. &lt;code&gt;test&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Leave it &lt;strong&gt;empty&lt;/strong&gt; (don't initialize with a README or &lt;code&gt;.gitignore&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create repository&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; There are ways to create a GitHub repository entirely from the terminal (e.g. using GitHub CLI or the REST API). But to keep things simple, we're creating it through the web interface here. We'll cover terminal-only workflows in a future post.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📂 Step 5: Initialize a local repository
&lt;/h2&gt;

&lt;p&gt;Back in your terminal, create a new folder and initialize a Git repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/test
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/test
git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a simple file to commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"My first Git-backed config!"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📥 Step 6: Add and commit your changes
&lt;/h2&gt;

&lt;p&gt;Stage the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Initial commit"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This records a snapshot of your project in Git history.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌐 Step 7: Connect local repo to GitHub
&lt;/h2&gt;

&lt;p&gt;In order to be able to push to the remote GitHub server, you have to connect your local repository to it.&lt;/p&gt;

&lt;p&gt;For this, copy the SSH URL from the GitHub repository page. &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%2Fxs9w4ikt3m7bi2lp7bws.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%2Fxs9w4ikt3m7bi2lp7bws.png" alt="SSH URL" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git@github.com:your-username/test.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now connect your local repo to that remote:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote add origin git@github.com:your-username/test.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git remote add&lt;/code&gt;: Creates a new remote connection.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;origin&lt;/code&gt;: The name (alias) you give to that remote (conventionally called &lt;code&gt;origin&lt;/code&gt;, but you can name it anything).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git@github.com:yourusername/test.git&lt;/code&gt;: The remote repository URL (over SSH in this case, not HTTPS).&lt;/li&gt;
&lt;li&gt;You are basically telling Git that the local repository now has a remote called &lt;code&gt;origin&lt;/code&gt;, and it lives at the provided URL (&lt;code&gt;git@github.com:...&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To list all currently configured remote repositories, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;origin  git@github.com:yourusername/test.git &lt;span class="o"&gt;(&lt;/span&gt;fetch&lt;span class="o"&gt;)&lt;/span&gt;
origin  git@github.com:yourusername/test.git &lt;span class="o"&gt;(&lt;/span&gt;push&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Note:&lt;/strong&gt; Git can use different URLs for pulling and pushing. Usually they're the same, but you can configure them separately. For example, if you push via SSH but fetch from a read-only HTTPS mirror.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  SSH vs HTTPS
&lt;/h3&gt;

&lt;p&gt;There are two main ways to connect your local Git repository to GitHub: &lt;strong&gt;SSH&lt;/strong&gt; and &lt;strong&gt;HTTPS&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SSH&lt;/strong&gt; (&lt;code&gt;git@github.com:...&lt;/code&gt;): This method uses your SSH key for authentication. Once your key is added to GitHub, Git can authenticate automatically, no username, password, or token required. It's usually the easiest and most seamless option for everyday use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTPS&lt;/strong&gt; (&lt;code&gt;https://github.com/...&lt;/code&gt;): This method uses an HTTPS connection instead of SSH. However, GitHub no longer accepts your regular password for Git operations. Instead, you'll need to create a &lt;strong&gt;Personal Access Token (PAT)&lt;/strong&gt; and use that as your password. You can generate a PAT in &lt;strong&gt;GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When using HTTPS, you'll clone or add your remote with the HTTPS URL. Then, when prompted for credentials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Username:&lt;/strong&gt; your GitHub username&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password:&lt;/strong&gt; your Personal Access Token (PAT)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both approaches work equally well. &lt;strong&gt;SSH&lt;/strong&gt; is usually the smoother choice for daily development because it "just works" once set up, while &lt;strong&gt;HTTPS + PAT&lt;/strong&gt; can be handy in automated scripts, CI/CD pipelines, or environments where SSH is blocked.&lt;/p&gt;

&lt;h2&gt;
  
  
  📤 Step 8: Push your file to GitHub
&lt;/h2&gt;

&lt;p&gt;Let's first rename the default branch named &lt;code&gt;master&lt;/code&gt; to &lt;code&gt;main&lt;/code&gt;, the modern convention used by most projects today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This is typically a one-off operation after you created a new repository. When you create new branches in the future, you'll name them yourself (e.g. &lt;code&gt;feature-branch&lt;/code&gt;), so you won't need to rename anything again unless you want to rename an existing branch.&lt;/p&gt;

&lt;p&gt;Further, not that if you haven't made any commits yet, this command will fail with an error like: &lt;/p&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;error: refname refs/heads/master not found
fatal: Branch rename failed
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;That's because no branch actually exists until you've made your first commit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then push to GitHub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-u&lt;/code&gt; (short for &lt;code&gt;--set-upstream&lt;/code&gt;): Creates the &lt;code&gt;main&lt;/code&gt; branch on remote (&lt;code&gt;origin&lt;/code&gt;) and links your local &lt;code&gt;main&lt;/code&gt; branch with that remote branch (&lt;code&gt;origin/main&lt;/code&gt;). &lt;/li&gt;
&lt;li&gt;Once this upstream relationship is established, you can use the short commands &lt;code&gt;git push&lt;/code&gt; and &lt;code&gt;git pull&lt;/code&gt; instead of typing the full forms &lt;code&gt;git push origin main&lt;/code&gt; and &lt;code&gt;git pull origin main&lt;/code&gt;, respectively, when working on the &lt;code&gt;main&lt;/code&gt; branch.&lt;/li&gt;
&lt;li&gt;Whenever you create a new branch (e.g. &lt;code&gt;git checkout -b feature-branch&lt;/code&gt;), you should also include &lt;code&gt;u&lt;/code&gt; the first time you push it to ensure the new local branch is linked to the corresponding remote branch (&lt;code&gt;origin/feature-branch&lt;/code&gt;), so you can use the short commands &lt;code&gt;git push&lt;/code&gt; and &lt;code&gt;git pull&lt;/code&gt; while working on &lt;code&gt;feature-branch&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;If you forget the &lt;code&gt;u&lt;/code&gt;, the &lt;code&gt;git push origin feature-branch&lt;/code&gt; may still succeed, but &lt;code&gt;git pull&lt;/code&gt; will give you an error &lt;code&gt;fatal: no upstream configure...&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To show all the local branches as well as their linked remote branches, run &lt;code&gt;git branch -vv&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;If everything is correct, you'll see something like:&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%2Fm5um350bdtedv5g1riro.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%2Fm5um350bdtedv5g1riro.png" alt=" " width="675" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📊 Step 9: Verify on GitHub
&lt;/h2&gt;

&lt;p&gt;Go to your new repository's page on GitHub. You should now see your &lt;code&gt;README.md&lt;/code&gt; file and your initial commit 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ Conclusion
&lt;/h2&gt;

&lt;p&gt;Congratulations! You've successfully installed Git on Ubuntu, connected it to GitHub, and pushed your first commit. This simple workflow is the foundation of virtually every modern software project.&lt;/p&gt;

&lt;p&gt;The next step is to deepen your understanding of Git's most common commands and workflows, things like branching, merging, and rebasing. The &lt;a href="https://confluence.atlassian.com/bitbucketserver/basic-git-commands-776639767.html" rel="noopener noreferrer"&gt;Git command reference by Atlassian&lt;/a&gt; is a great place to continue the learning path.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: I use ChatGPT to help me gather information and shape these posts, but I always test the commands myself and add my own insights to make them easier to understand. This blog is my personal record of what I learn as I go deeper into Linux. If it helps someone else too, even better!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>ubuntu</category>
      <category>github</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to back up and sync your terminal configuration with a GitHub dotfiles repo</title>
      <dc:creator>100x.crypto 🚀🚀</dc:creator>
      <pubDate>Tue, 14 Oct 2025 07:40:03 +0000</pubDate>
      <link>https://dev.to/walodja1987/how-to-back-up-and-sync-your-terminal-configuration-with-a-github-dotfiles-repo-4p17</link>
      <guid>https://dev.to/walodja1987/how-to-back-up-and-sync-your-terminal-configuration-with-a-github-dotfiles-repo-4p17</guid>
      <description>&lt;p&gt;If you use Ubuntu (or any Linux system) regularly, chances are you've customized it over time, adding handy aliases, defining environment variables, tweaking your shell prompt, and installing useful tools.&lt;/p&gt;

&lt;p&gt;These small changes make your system feel yours. But here is the problem: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 What happens if your system breaks, gets wiped, or you switch to a new machine?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If all your configuration lives only on one device, you could lose hours — even days — of work rebuilding your environment from scratch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The solution:&lt;/strong&gt; Store your configuration files ("dotfiles") in a GitHub repository.&lt;br&gt;
This not only backs them up but also makes it easy to sync them across devices and restore your setup instantly on a new machine.&lt;/p&gt;

&lt;p&gt;This guide shows you how to do exactly that, step by step.&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀 Step 1: Organize your config files
&lt;/h2&gt;

&lt;p&gt;Let's say you would like to back up your &lt;code&gt;~/.bashrc&lt;/code&gt; and &lt;code&gt;~/.bash_aliases&lt;/code&gt; files (you can apply the same approach to any other config file).&lt;/p&gt;

&lt;p&gt;First, create a dedicated folder within your home directory (&lt;code&gt;~&lt;/code&gt;) to hold your dotfiles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/dotfiles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now copy your config files into that folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; ~/.bashrc ~/dotfiles/bashrc
&lt;span class="nb"&gt;cp&lt;/span&gt; ~/.bash_aliases ~/dotfiles/bash_aliases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; To view your dotfiles in your home directory (hidden by default), use &lt;code&gt;ls -a&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Security Warning:&lt;/strong&gt;&lt;br&gt;
Be very careful &lt;strong&gt;not to include sensitive files&lt;/strong&gt; in your dotfiles repository — especially if it's public.&lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;Never commit&lt;/strong&gt; files like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;~/.ssh/*&lt;/code&gt; (private SSH keys)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;~/.aws/credentials&lt;/code&gt; (cloud access keys)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.env&lt;/code&gt; files with API keys or passwords&lt;/li&gt;
&lt;li&gt;GPG keys or database credentials&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If someone gains access to these files, they could impersonate you, access your servers, or compromise your accounts.&lt;/p&gt;

&lt;p&gt;✅ Best practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only track &lt;strong&gt;safe, reusable configuration files&lt;/strong&gt; (like &lt;code&gt;.bashrc&lt;/code&gt;, &lt;code&gt;.bash_aliases&lt;/code&gt;, &lt;code&gt;.gitconfig&lt;/code&gt;, etc.).&lt;/li&gt;
&lt;li&gt;Add sensitive files to &lt;code&gt;.gitignore&lt;/code&gt; so they’re never pushed by mistake.&lt;/li&gt;
&lt;li&gt;Consider using a &lt;strong&gt;private repository&lt;/strong&gt; if you absolutely must store sensitive configs — and even then, avoid committing secrets directly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🧰 Step 2: Initialize a Git repository
&lt;/h2&gt;

&lt;p&gt;Log in to your GitHub account in your browser and create a new repository called &lt;code&gt;dotfiles&lt;/code&gt;. Leave it empty (i.e., don't initialize with a README or &lt;code&gt;.gitignore&lt;/code&gt;). We'll add the files from our local machine shortly.&lt;/p&gt;

&lt;p&gt;Now navigate to your newly created local &lt;code&gt;dotfiles&lt;/code&gt; folder via&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/dotfiles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and turn it into a Git repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Initial backup of my shell config"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your configuration files are now tracked by Git locally.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Note:&lt;/strong&gt; If you don't have Git installed or run into issues here, check out &lt;a href="https://dev.to/walodja1987/how-to-install-git-on-ubuntu-and-push-your-first-repository-to-github-21gl"&gt;my other post on how to install Git and push your first repository&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🐙 Step 3: Push it to GitHub
&lt;/h2&gt;

&lt;p&gt;Next, connect your local repository to the remote one you just created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote add origin git@github.com:yourusername/dotfiles.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now rename the branch from its default name &lt;code&gt;master&lt;/code&gt; to &lt;code&gt;main&lt;/code&gt; (modern convention) via&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;…and push your local files to GitHub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything worked correctly, you should now see your &lt;code&gt;bashrc&lt;/code&gt; and &lt;code&gt;bash_aliases&lt;/code&gt; files listed in your GitHub repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Step 4: Restore your setup on a new machine
&lt;/h2&gt;

&lt;p&gt;Here's where the magic happens. If you ever reinstall your OS or switch to a new device, you can bring your setup back with just a few commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@github.com:Walodja1987/dotfiles.git ~/dotfiles
&lt;span class="nb"&gt;cp&lt;/span&gt; ~/dotfiles/bashrc ~/.bashrc
&lt;span class="nb"&gt;cp&lt;/span&gt; ~/dotfiles/bash_aliases ~/.bash_aliases
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom! Your terminal is back exactly how you left it.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Note on SSH vs HTTPS:&lt;/strong&gt;&lt;br&gt;
In the example above, I cloned the repo using the &lt;strong&gt;SSH URL&lt;/strong&gt; (&lt;code&gt;git@github.com:...&lt;/code&gt;), which lets Git authenticate automatically using your SSH key, without a password or token. &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%2Fxs9w4ikt3m7bi2lp7bws.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%2Fxs9w4ikt3m7bi2lp7bws.png" alt=" " width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once your SSH key is configured on GitHub, this is usually the easiest option. Check out my other post no how to set up the SSH key.&lt;/p&gt;

&lt;p&gt;If you prefer to use &lt;strong&gt;HTTPS&lt;/strong&gt;, you can do so, but GitHub no longer accepts passwords for Git operations. Instead, you'll need to use a &lt;strong&gt;Personal Access Token (PAT)&lt;/strong&gt; as your password when prompted (you find the PAT in GitHub under Settings -&amp;gt; Developer Settings -&amp;gt; Personal access tokens -&amp;gt; Tokens (classic)):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/yourusername/dotfiles.git ~/dotfiles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Username:&lt;/strong&gt; your GitHub username&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password:&lt;/strong&gt; your Personal Access Token (PAT)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both methods work, but SSH is often smoother for day-to-day use, while HTTPS + PAT can be useful in scripts or CI/CD pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Step 5: Keep it up to date
&lt;/h2&gt;

&lt;p&gt;Whenever you tweak your local dotfiles, just update your repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; ~/.bash_aliases ~/dotfiles/bash_aliases
&lt;span class="nb"&gt;cp&lt;/span&gt; ~/.bashrc ~/dotfiles/bashrc
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/dotfiles
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Update aliases and bashrc"&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures your GitHub repo always mirrors your current setup and your latest configuration is always just a &lt;code&gt;git clone&lt;/code&gt; away.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Treating your shell configuration like code — version-controlled, backed up, and portable — is one of the most valuable habits you can develop as a developer or power user.&lt;/p&gt;

&lt;p&gt;With a simple dotfiles repository on GitHub, your carefully crafted setup is safe, reproducible, and always within reach, no matter what happens to your system.&lt;/p&gt;

&lt;p&gt;If you want to take it one step further, check out my &lt;a href="https://dev.to/walodja1987/symlinks-2gjh"&gt;follow-up post on how to use symlinks to keep your dotfiles automatically in sync&lt;/a&gt;. It shows how to avoid manual copying altogether and make the process even more seamless.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: I use ChatGPT to help me gather information and shape these posts, but I always test the commands myself and add my own insights to make them easier to understand. This blog is my personal record of what I learn as I go deeper into Linux. If it helps someone else too, even better!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>linux</category>
      <category>tooling</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Test installs in a clean Ubuntu sandbox</title>
      <dc:creator>100x.crypto 🚀🚀</dc:creator>
      <pubDate>Sun, 12 Oct 2025 14:51:41 +0000</pubDate>
      <link>https://dev.to/walodja1987/test-installs-in-a-clean-ubuntu-sandbox-p7p</link>
      <guid>https://dev.to/walodja1987/test-installs-in-a-clean-ubuntu-sandbox-p7p</guid>
      <description>&lt;p&gt;When you include installation guides in your tutorials or documentation, it's good practice to test the installation steps. But what if you already have the tool installed on your machine and don't want to uninstall it?&lt;/p&gt;

&lt;p&gt;Here's a simple, elegant solution: use &lt;strong&gt;Docker&lt;/strong&gt; to spin up a fresh Ubuntu environment in seconds, no changes to your existing setup required.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This guide is written for Ubuntu. Windows and macOS are not covered here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🛠️ Step 1: Install Docker (if not already installed)
&lt;/h2&gt;

&lt;p&gt;Check whether &lt;code&gt;docker&lt;/code&gt; is already installed on your system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;docker&lt;/code&gt; is not yet installed on your Ubuntu system, install it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;docker.io &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then start the Docker service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;service docker start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can verify the installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker version 26.1.3, build 26.1.3-0ubuntu1~20.04.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧪 Step 2: Launch a fresh Ubuntu container
&lt;/h2&gt;

&lt;p&gt;Now spin up a fresh Ubuntu 22.04 container with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; ubuntu:22.04 bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker run&lt;/code&gt; – creates and runs a container&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-it&lt;/code&gt; – makes it interactive (so you can use it like a shell)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ubuntu:22.04&lt;/code&gt; – pulls the official Ubuntu image from Docker Hub&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bash&lt;/code&gt; – starts a Bash shell inside the container&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You're now inside a &lt;strong&gt;clean Ubuntu environment&lt;/strong&gt;, just like a fresh server install.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Note:&lt;/strong&gt; The official &lt;code&gt;ubuntu:22.04&lt;/code&gt; Docker image is extremely minimal. It doesn't even include &lt;code&gt;sudo&lt;/code&gt; by default. And since you're already logged in as the &lt;code&gt;root&lt;/code&gt; user inside the container (notice the &lt;code&gt;root@...:/#&lt;/code&gt; prompt), you will not need &lt;code&gt;sudo&lt;/code&gt; in front of any commands. For example, you can simply run &lt;code&gt;apt update&lt;/code&gt; instead of &lt;code&gt;sudo apt update&lt;/code&gt;. If you try the latter, you'll see &lt;code&gt;bash: sudo: command not found&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Step 3: Test installation steps
&lt;/h2&gt;

&lt;p&gt;Let's test the installation of the &lt;code&gt;curl&lt;/code&gt; tool.&lt;/p&gt;

&lt;p&gt;Inside the container, try running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll likely get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bash: curl: command not found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is exactly what we want. Now you can follow your installation guide exactly as a new user would:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt update
apt &lt;span class="nb"&gt;install &lt;/span&gt;curl &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then verify again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now see the installed version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl 7.88.1 (x86_64-pc-linux-gnu) libcurl/7.88.1 OpenSSL/3.0.2 ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧹 Step 4: Exit and throw away the test environment
&lt;/h2&gt;

&lt;p&gt;When you're done testing, simply type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The container stops and disappears. Your real system remains unchanged, and you can spin up a new clean one anytime by running the same command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; ubuntu:22.04 bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✨ Conclusion
&lt;/h2&gt;

&lt;p&gt;Using Docker to simulate a clean Linux environment is one of the easiest ways to &lt;strong&gt;validate installation instructions&lt;/strong&gt; without touching your real system. It’s quick, lightweight, and repeatable.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: I use ChatGPT to help me gather information and shape these posts, but I always test the commands myself and add my own insights to make them easier to understand. This blog is my personal record of what I learn as I go deeper into Linux. If it helps someone else too, even better!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>testing</category>
      <category>tutorial</category>
      <category>docker</category>
    </item>
    <item>
      <title>Boost your terminal workflow with aliases</title>
      <dc:creator>100x.crypto 🚀🚀</dc:creator>
      <pubDate>Sun, 12 Oct 2025 14:29:36 +0000</pubDate>
      <link>https://dev.to/walodja1987/boost-your-terminal-workflow-with-aliases-42cg</link>
      <guid>https://dev.to/walodja1987/boost-your-terminal-workflow-with-aliases-42cg</guid>
      <description>&lt;p&gt;If you often work in the terminal, you've probably found yourself looking up and typing the same long commands again and again. Whether it's starting a service, launching a Docker container, or running a script, those commands are hard to remember and slow you down your workflow.&lt;/p&gt;

&lt;p&gt;Fortunately, there's a simple trick that makes your life much easier: &lt;strong&gt;aliases&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An alias is a short, memorable word you define to stand in for a longer command.&lt;/strong&gt; It's one of the simplest and most powerful ways to make your command-line experience faster, cleaner, and more enjoyable.&lt;/p&gt;

&lt;p&gt;Let's see how it works. 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Example
&lt;/h2&gt;

&lt;p&gt;Imagine you're frequently running these two commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;service docker start
&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; ubuntu:22.04 bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first starts the Docker service, and the second launches a fresh Ubuntu container (see my &lt;a href="https://dev.to/walodja1987/test-installs-in-a-clean-ubuntu-sandbox-p7p"&gt;other blog post&lt;/a&gt; to learn where this combination can be helpful). Both are useful, but memorizing and typing them every time is tedious.&lt;/p&gt;

&lt;p&gt;With aliases, you can replace those long commands with simple, human-friendly words like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;startdocker
freshubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧪 Step 1: Create temporary aliases (for testing)
&lt;/h2&gt;

&lt;p&gt;You can define an alias directly in your terminal. It will work until you close the session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;startdocker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'sudo service docker start'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;freshubuntu&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'sudo docker run -it ubuntu:22.04 bash'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now try them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;startdocker
freshubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Much cleaner and easier to remember.&lt;/p&gt;

&lt;p&gt;If you want to change the command associated with an alias, just redefine it with the new command. The new definition will overwrite the old one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You need to have Docker installed to run these commands. If you don't have Docker, either install it via&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;docker.io &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...or try other commands you use frequently. &lt;/p&gt;

&lt;h2&gt;
  
  
  🔁 Step 2: Make aliases permanent
&lt;/h2&gt;

&lt;p&gt;Temporary aliases disappear when you close the terminal. To make them permanent, add them to your shell configuration file.&lt;/p&gt;

&lt;p&gt;For bash (Ubuntu's default shell):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add your aliases at the bottom:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;startdocker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'sudo service docker start'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;freshubuntu&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'sudo docker run -it ubuntu:22.04 bash'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and exit (&lt;code&gt;CTRL+O&lt;/code&gt;, &lt;code&gt;Enter&lt;/code&gt;, &lt;code&gt;CTRL+X&lt;/code&gt;), then reload the configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now these aliases will work every time you open a new terminal window.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you're using zsh instead of bash, add aliases to &lt;code&gt;~/.zshrc&lt;/code&gt; instead of &lt;code&gt;~/.bashrc&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🔗 Combine multiple commands into a single alias
&lt;/h2&gt;

&lt;p&gt;Aliases can do more than just shorten single commands. They can chain multiple commands together.&lt;/p&gt;

&lt;p&gt;For example, you could create an alias that starts Docker and then launches the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;freshubuntu&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'sudo service docker start &amp;amp;&amp;amp; sudo docker run -it ubuntu:22.04 bash'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, typing:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;…will automatically start the Docker service (if needed) and drop you into a fresh Ubuntu environment, all in one step.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Useful tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Command to list all defined aliases:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Some aliases may already be defined by default in your system’s .bashrc or other startup files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Command to remove an alias:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;unalias &lt;/span&gt;freshubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Best practices:

&lt;ul&gt;
&lt;li&gt;Use short, meaningful names.&lt;/li&gt;
&lt;li&gt;Keep a consistent naming convention (e.g., all lowercase).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  📂 Optional: Store aliases in a separate file
&lt;/h2&gt;

&lt;p&gt;As your list of aliases grows, it can clutter your &lt;code&gt;~/.bashrc&lt;/code&gt;. A cleaner approach is to store them in a dedicated &lt;code&gt;~/.bash_aliases&lt;/code&gt; file and then load that file from &lt;code&gt;.bashrc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 – Create the &lt;code&gt;.bash_aliases&lt;/code&gt; file:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano ~/.bash_aliases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your shortcuts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;startdocker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'sudo service docker start'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;freshubuntu&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'sudo docker run -it ubuntu:22.04 bash'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and exit the file (&lt;code&gt;CTRL+O&lt;/code&gt;, &lt;code&gt;Enter&lt;/code&gt;, &lt;code&gt;CTRL+X&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 – Source it from &lt;code&gt;.bashrc&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open your &lt;code&gt;~/.bashrc&lt;/code&gt; and add this snippet near the bottom:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.bash_aliases &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bash_aliases
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells your shell to load all aliases from &lt;code&gt;~/.bash_aliases&lt;/code&gt; if the file exists.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You may already have this &lt;code&gt;if&lt;/code&gt;-block in your &lt;code&gt;.bashrc&lt;/code&gt; file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now reload your configuration to apply the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that approach, your &lt;code&gt;~/.bashrc&lt;/code&gt; stays clean, and you can back up or share your aliases separately without touching the rest of your configuration.&lt;/p&gt;

&lt;p&gt;This small structure change pays off later, especially when you start version-controlling your config (as we'll explore in the next post).&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ Conclusion
&lt;/h2&gt;

&lt;p&gt;Aliases are a small trick that deliver big productivity gains. With just a few lines in your shell config, you can turn long, hard-to-remember commands into short, memorable shortcuts, saving time and making your workflow more enjoyable.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: I use ChatGPT to help me gather information and shape these posts, but I always test the commands myself and add my own insights to make them easier to understand. This blog is my personal record of what I learn as I go deeper into Linux. If it helps someone else too, even better!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cli</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
