<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ codespaces - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ codespaces - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 18 May 2026 10:47:31 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/codespaces/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Run Python GUI Apps in GitHub Codespaces with Xvfb and noVNC ]]>
                </title>
                <description>
                    <![CDATA[ GitHub Codespaces gives you a full development environment in the cloud, directly in your browser. It’s great for writing and running code, but there’s one big limitation: it doesn’t support graphical applications out of the box, especially for Pytho... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/run-python-gui-in-github-codespaces/</link>
                <guid isPermaLink="false">68c4a196984613262158d040</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ codespaces ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ayodele Aransiola ]]>
                </dc:creator>
                <pubDate>Fri, 12 Sep 2025 22:41:26 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1757716674058/86bb9af9-0977-4548-a050-36c3b9ea3e16.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>GitHub Codespaces gives you a full development environment in the cloud, directly in your browser. It’s great for writing and running code, but there’s one big limitation: it doesn’t support graphical applications out of the box, especially for Python code.</p>
<p>If you try to run a Python GUI library like Pygame, Tkinter, or PyQt inside Codespaces, you’ll get an error. That’s because Codespaces runs in a headless environment. There’s no physical display for your app to open a window on.</p>
<p>In this article, I’ll show you how to fix that. You’ll learn how to set up a virtual desktop using Xvfb and stream it into your browser using noVNC. By the end, you’ll be able to run any Python GUI application inside GitHub Codespaces.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#why-codespaces-needs-extra-setup-for-guis">Why Codespaces Needs Extra Setup for GUIs</a></p>
</li>
<li><p><a class="post-section-overview" href="#step-1-create-the-repo-and-open-codespace">Step 1: Create the Repo and Open Codespace</a></p>
</li>
<li><p><a class="post-section-overview" href="#step-2-add-the-setup-script">Step 2: Add the Setup Script</a></p>
</li>
<li><p><a class="post-section-overview" href="#step-3-start-the-gui-environment">Step 3: Start the GUI Environment</a></p>
</li>
<li><p><a class="post-section-overview" href="#step-4-open-the-novnc-desktop">Step 4: Open the noVNC Desktop</a></p>
</li>
<li><p><a class="post-section-overview" href="#step-5-run-your-python-gui-app">Step 5: Run Your Python GUI App</a></p>
</li>
<li><p><a class="post-section-overview" href="#tips">Tips</a></p>
</li>
<li><p><a class="post-section-overview" href="#conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you start, you should have:</p>
<ul>
<li><p>A GitHub account and access to GitHub Codespaces.</p>
</li>
<li><p>Basic familiarity with Python.</p>
</li>
<li><p>A Python GUI app to test (we’ll use a small Pygame example).</p>
</li>
</ul>
<h2 id="heading-why-codespaces-needs-extra-setup-for-guis">Why Codespaces Needs Extra Setup for GUIs</h2>
<p>When you run GUI code like:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pygame
pygame.display.set_mode((<span class="hljs-number">800</span>, <span class="hljs-number">600</span>))
</code></pre>
<p>On your local machine, Python tells your operating system to create a window. But Codespaces runs on a server with no monitor attached. Without a display, your GUI app cannot render.</p>
<p>That’s where <a target="_blank" href="https://www.x.org/archive/X11R7.7/doc/man/man1/Xvfb.1.xhtml"><strong>Xvfb</strong></a> (X virtual framebuffer) comes in. It simulates a display in memory, so GUI programs think they’re running on a real screen. To make that screen visible in the browser, you can use <a target="_blank" href="https://novnc.com/info.html"><strong>noVNC</strong></a>, which streams the virtual display through a web client.</p>
<p>Together, Xvfb and noVNC turn Codespaces into a cloud-based desktop for GUI apps.</p>
<h2 id="heading-step-1-create-the-repo-and-open-codespace">Step 1: Create the Repo and Open Codespace</h2>
<p>First, create a GitHub repository for your project (or a demo repo) and open it in Codespaces:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757336978616/4a41c394-0d85-48de-b7d6-14a0a3dae56d.jpeg" alt="Screenshot of a new repository" class="image--center mx-auto" width="1080" height="1080" loading="lazy"></p>
<h2 id="heading-step-2-add-the-setup-script">Step 2: Add the Setup Script</h2>
<p>Create a file called <code>start-gui.sh</code> in the root of your project.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757337705472/b1b75b17-57b9-437c-a79e-18f6b1f55cae.png" alt="a screenshot of GitHub codespace with a bash file created" class="image--center mx-auto" width="1080" height="1080" loading="lazy"></p>
<p>Paste the following code into the <code>start-gui.sh</code> file:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/usr/bin/env bash</span>
<span class="hljs-built_in">set</span> -e

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Installing dependencies..."</span>
sudo apt-get update -y
sudo apt-get install -y xvfb x11vnc fluxbox websockify novnc

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Starting virtual display..."</span>
Xvfb :1 -screen 0 1024x768x24 &amp;
<span class="hljs-built_in">export</span> DISPLAY=:1
fluxbox &amp;

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Starting VNC server..."</span>
x11vnc -display :1 -nopw -forever -shared -rfbport 5900 &amp;

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Starting noVNC on port 6080..."</span>
websockify --web=/usr/share/novnc 6080 localhost:5900 &amp;

<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"GUI environment is ready!"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Go to the Ports tab, set port 6080 to Public, and open the link."</span>
</code></pre>
<p>Let’s explain this script so you can understand what it does:</p>
<h3 id="heading-set-e"><code>set -e</code></h3>
<ul>
<li><p>This tells the shell to exit immediately if any command fails.</p>
</li>
<li><p>Without it, the script would keep running even if something goes wrong (like a failed install).</p>
</li>
</ul>
<h3 id="heading-installing-dependencies">Installing Dependencies</h3>
<p><code>sudo apt-get update -y</code>: updates your package list.</p>
<p><code>sudo apt-get install -y</code> ⁣installs the packages we listed (xvfb, x11vnc, fluxbox, websockify, and novnc)</p>
<ul>
<li><ul>
<li><p><strong>xvfb</strong>: creates a “dummy” display (virtual screen in memory).</p>
<ul>
<li><p><strong>x11vnc</strong>: shares that dummy display via the VNC protocol.</p>
</li>
<li><p><strong>Fluxbox:</strong> a lightweight window manager, so the desktop has a GUI environment.</p>
</li>
<li><p><strong>websockify</strong>: converts VNC traffic into WebSockets so it can run in a browser.</p>
</li>
<li><p><strong>novnc</strong>: provides a browser client to connect to the desktop.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="heading-virtual-display">Virtual Display</h3>
<ul>
<li><p><code>Xvfb :1 -screen 0 1024x768x24 &amp;</code>: Starts the virtual framebuffer on display <code>:1</code> with resolution <code>1024x768</code> and 24-bit color.</p>
</li>
<li><p><code>export DISPLAY=:1</code>: tells apps (like Python GUIs) to draw on this virtual screen instead of looking for a real display unit.</p>
</li>
<li><p><code>fluxbox &amp;</code>: launches the window manager so GUI apps have a desktop to sit in.</p>
</li>
</ul>
<h3 id="heading-vnc-server">VNC Server</h3>
<ul>
<li><p><code>x11vnc -display :1</code>: connects you to the dummy display (<code>:1</code>).</p>
</li>
<li><p><code>-nopw</code>: ensures that no password is required.</p>
</li>
<li><p><code>-forever</code>: this keeps the VNC running even if clients disconnect.</p>
</li>
<li><p><code>-shared</code>: allows multiple clients.</p>
</li>
<li><p><code>-rfbport 5900</code>: exposes the internal server on VNC’s standard port.</p>
</li>
</ul>
<h3 id="heading-novnc-server">noVNC Server</h3>
<ul>
<li><p><code>websockify</code> acts as a bridge that converts WebSocket traffic to VNC protocol (on port 5900).</p>
</li>
<li><p><code>--web=/usr/share/novnc</code>: serves the noVNC web client files.</p>
</li>
<li><p><code>6080</code>: the port where you’ll connect in your browser (this is publicly accessible).</p>
</li>
<li><p><a target="_blank" href="http://localhost:5900"><code>localhost:5900</code></a>:forwards traffic to the VNC server that was started earlier.</p>
</li>
</ul>
<p>You should only expose <strong>port 6080</strong> (noVNC) as <strong>Public</strong> and keep <strong>5900</strong> (raw VNC) private because:</p>
<ul>
<li><p><strong>Prt 5900 (VNC)</strong> uses the raw VNC protocol, which is <strong>not encrypted</strong> and doesn’t require a password in this setup. If exposed, anyone could connect directly and control your Codespace desktop.</p>
</li>
<li><p><strong>Prt 6080 (noVNC)</strong> runs over <strong>WebSockets + HTTPS</strong>, so traffic is encrypted and secured through GitHub Codespaces’ connection. It also only serves the noVNC web client, not the raw VNC protocol.</p>
</li>
</ul>
<blockquote>
<p><strong>5900 = unsafe to expose</strong>, <strong>6080 = browser-safe way to view the GUI</strong>.</p>
</blockquote>
<p>The next step is for you to make the bash file executable by running the code below in the terminal:</p>
<pre><code class="lang-bash">chmod +x start-gui.sh
</code></pre>
<h2 id="heading-step-3-start-the-gui-environment">Step 3: Start the GUI Environment</h2>
<p>Run the script:</p>
<pre><code class="lang-bash">./start-gui.sh
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757339165120/f99b3381-d038-4eb6-944d-3fabad058c95.png" alt="the terminal while running the bash script" class="image--center mx-auto" width="1080" height="1080" loading="lazy"></p>
<p>This will:</p>
<ol>
<li><p>Install all dependencies (Xvfb, fluxbox, x11vnc, novnc).</p>
</li>
<li><p>Start a virtual display (<code>DISPLAY=:1</code>).</p>
</li>
<li><p>Launch a lightweight window manager (fluxbox).</p>
</li>
<li><p>Stream the desktop to your browser via noVNC on port <code>6080</code>.</p>
</li>
</ol>
<h2 id="heading-step-4-open-the-novnc-desktop">Step 4: Open the noVNC Desktop</h2>
<ol>
<li><p>In Codespaces, open the Ports tab.</p>
</li>
<li><p>Find port 6080 and change its visibility to public. (right-click on the private word)</p>
</li>
<li><p>Open the URL in a new browser tab.</p>
</li>
<li><p>Click <code>vnc.html</code> or <code>vnc_auto.html</code> if prompted.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757339315843/e3fcfd7b-d946-4c46-b4a9-09b905574a80.png" alt="screenshot of the port tab on codespace" class="image--center mx-auto" width="1394" height="331" loading="lazy"></p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757339400603/d8e0e412-7669-4c41-b1e4-5f13d8125de1.png" alt="open the port 6080 forwared address in a new tab, and you'd get this screen" class="image--center mx-auto" width="413" height="256" loading="lazy"></p>
<p>You should now see a lightweight Linux desktop running inside your browser.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757339486345/f5831d0e-d66e-4549-902a-13e3c8bd8bf0.png" alt="a light weight linux desktop running on your browser" class="image--center mx-auto" width="1443" height="1077" loading="lazy"></p>
<h2 id="heading-step-5-run-your-python-gui-app">Step 5: Run Your Python GUI App</h2>
<p>In a new Codespaces terminal, run:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> DISPLAY=:<span class="hljs-number">1</span>
python3 your_script.py
</code></pre>
<p>Your Python GUI app should appear inside the noVNC desktop 🎉.</p>
<p>For example, here’s a simple Pygame script <code>test.py</code>:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> pygame
<span class="hljs-keyword">from</span> pygame <span class="hljs-keyword">import</span> display, font, event
<span class="hljs-keyword">from</span> pygame.locals <span class="hljs-keyword">import</span> *

<span class="hljs-comment"># Setup display</span>
pygame.init()
screen = display.set_mode()
display.set_caption(<span class="hljs-string">"Capstone 2"</span>)
myFont = font.SysFont(<span class="hljs-string">'arial'</span>, <span class="hljs-number">12</span>)  <span class="hljs-comment"># Choose a font to use in game</span>

<span class="hljs-comment"># Directions displayed throughout game</span>
directions = <span class="hljs-string">"Please press the 'Y' key for yes and the 'N' key for no."</span>

<span class="hljs-comment"># Counts how many questions have been asked</span>
currentQuestion = <span class="hljs-number">0</span>


<span class="hljs-comment"># Determines which question to ask</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">story</span>(<span class="hljs-params">answer, count</span>):</span>
    screen.fill(<span class="hljs-string">"white"</span>)
    <span class="hljs-keyword">if</span> count == <span class="hljs-number">0</span>:
        question1(answer)
    <span class="hljs-keyword">elif</span> count == <span class="hljs-number">1</span>:
        question2(answer)
    <span class="hljs-keyword">elif</span> count == <span class="hljs-number">2</span>:
        question3(answer)
    <span class="hljs-keyword">elif</span> count == <span class="hljs-number">3</span>:
        end(answer)


<span class="hljs-comment"># Displays the first part of the story</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">intro</span>():</span>
    <span class="hljs-comment"># Break up the string into multiple variables because there isn't text wrapping in Pygame</span>
    intro1 = <span class="hljs-string">"Once upon a time lived a brave hero named Anya."</span>
    intro2 = <span class="hljs-string">"She lived a simple life in a small village, making biscuits for the village people."</span>
    intro3 = <span class="hljs-string">"One day, late at night, she hears a loud noise outside the village."</span>
    q1 = <span class="hljs-string">"Should she go outside to investigate? Yes or no?"</span>

    screen.fill(<span class="hljs-string">"white"</span>)
    textSurface = myFont.render(intro1, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
    screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">10</span>))
    textSurface = myFont.render(intro2, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
    screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">24</span>))
    textSurface = myFont.render(intro3, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
    screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">38</span>))
    textSurface = myFont.render(q1, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
    screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">52</span>))
    textSurface = myFont.render(directions, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
    screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">66</span>))


<span class="hljs-comment"># First question</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">question1</span>(<span class="hljs-params">answer</span>):</span>
    <span class="hljs-keyword">if</span> answer == K_y:
        yes1 = <span class="hljs-string">"She ventures into the dark, prepared for danger."</span>
        yes2 = <span class="hljs-string">"Eventually, she sees an army of ogres coming toward her village!"</span>
        q2 = <span class="hljs-string">"Should she fight the ogres? Yes or no?"</span>

        textSurface = myFont.render(yes1, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">10</span>))
        textSurface = myFont.render(yes2, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">24</span>))
        textSurface = myFont.render(q2, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">38</span>))
        textSurface = myFont.render(directions, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">52</span>))

    <span class="hljs-keyword">elif</span> answer == K_n:
        no1 = <span class="hljs-string">"She chooses the safety of her home and stays inside."</span>
        no2 = <span class="hljs-string">"However, the sounds do not go away."</span>
        no3 = <span class="hljs-string">"She can tell something is very wrong..."</span>
        no4 = <span class="hljs-string">"Eventually, she sees an army of ogres coming toward her village!"</span>
        q2 = <span class="hljs-string">"Should she fight the ogres? Yes or no?"</span>

        textSurface = myFont.render(no1, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">10</span>))
        textSurface = myFont.render(no2, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">24</span>))
        textSurface = myFont.render(no3, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">38</span>))
        textSurface = myFont.render(no4, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">52</span>))
        textSurface = myFont.render(q2, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">66</span>))
        textSurface = myFont.render(directions, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">80</span>))


<span class="hljs-comment"># Second question</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">question2</span>(<span class="hljs-params">answer</span>):</span>
    <span class="hljs-keyword">if</span> answer == K_y:
        yes1 = <span class="hljs-string">"She bravely confronts the ogres, hoping to protect her village from harm."</span>
        textSurface = myFont.render(yes1, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">10</span>))

    <span class="hljs-keyword">elif</span> answer == K_n:
        no1 = <span class="hljs-string">"The ogres raid the village but Anya manages to escape with her life."</span>
        textSurface = myFont.render(no1, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">10</span>))

    story2 = <span class="hljs-string">"The ogres decide to leave but she knows they will be back."</span>
    story3 = <span class="hljs-string">"Anya decides to talk with a village elder about what she should do."</span>
    story4 = <span class="hljs-string">"The elder says there is a powerful sword hidden in the Ancient Forest."</span>
    q3 = <span class="hljs-string">"Should Anya risk her life to retrieve it? Yes or no?"</span>

    textSurface = myFont.render(story2, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
    screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">24</span>))
    textSurface = myFont.render(story3, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
    screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">38</span>))
    textSurface = myFont.render(story4, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
    screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">52</span>))
    textSurface = myFont.render(q3, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
    screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">66</span>))
    textSurface = myFont.render(directions, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
    screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">80</span>))


<span class="hljs-comment"># Third question</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">question3</span>(<span class="hljs-params">answer</span>):</span>
    <span class="hljs-keyword">if</span> answer == K_y:
        yes1 = <span class="hljs-string">"Although Anya almost died in the Ancient Forest,"</span>
        yes2 = <span class="hljs-string">"she returns with the Sword of Legends!"</span>
        yes3 = <span class="hljs-string">"In the dead of winter, the ogres come back."</span>
        yes4 = <span class="hljs-string">"This time they are being led by their evil king."</span>
        q4 = <span class="hljs-string">"Should Anya fight the ogre king now that she has the Sword of Legends?"</span>

        textSurface = myFont.render(yes1, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">10</span>))
        textSurface = myFont.render(yes2, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">24</span>))
        textSurface = myFont.render(yes3, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">38</span>))
        textSurface = myFont.render(yes4, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">52</span>))
        textSurface = myFont.render(q4, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">66</span>))
        textSurface = myFont.render(directions, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">80</span>))

    <span class="hljs-keyword">elif</span> answer == K_n:
        no1 = <span class="hljs-string">"Anya decides it's too risky to go into the forest alone."</span>
        no2 = <span class="hljs-string">"She hopes for the best with the weapons she has."</span>
        no3 = <span class="hljs-string">"In the dead of winter, the ogres come back."</span>
        no4 = <span class="hljs-string">"This time they are being led by their evil king."</span>
        q4 = <span class="hljs-string">"Should Anya fight the king even though she doesn't have the Sword of Legends?"</span>

        textSurface = myFont.render(no1, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">10</span>))
        textSurface = myFont.render(no2, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">24</span>))
        textSurface = myFont.render(no3, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">38</span>))
        textSurface = myFont.render(no4, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">52</span>))
        textSurface = myFont.render(q4, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">66</span>))
        textSurface = myFont.render(directions, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">80</span>))


<span class="hljs-comment"># Ending</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">end</span>(<span class="hljs-params">answer</span>):</span>
    <span class="hljs-keyword">if</span> answer == K_y:
        yes1 = <span class="hljs-string">"Tension fills the air as she prepares to fight the king. The duel commences..."</span>
        end1 = <span class="hljs-string">"After an intense battle, Anya strikes the final blow!"</span>
        end2 = <span class="hljs-string">"The king surrenders and pleads for mercy."</span>
        end3 = <span class="hljs-string">"Anya is a true hero, who shows mercy to the king."</span>
        end4 = <span class="hljs-string">"This act of kindness warms the evil king's heart,"</span>
        end5 = <span class="hljs-string">"who promises to leave the village alone for eternity."</span>
        end6 = <span class="hljs-string">"The end!"</span>

        textSurface = myFont.render(yes1, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">10</span>))
        textSurface = myFont.render(end1, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">24</span>))
        textSurface = myFont.render(end2, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">38</span>))
        textSurface = myFont.render(end3, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">52</span>))
        textSurface = myFont.render(end4, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">66</span>))
        textSurface = myFont.render(end5, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">80</span>))
        textSurface = myFont.render(end6, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">94</span>))

    <span class="hljs-keyword">elif</span> answer == K_n:
        no1 = <span class="hljs-string">"Anya refuses to duel the king, who laughs at her cowardice."</span>
        end1 = <span class="hljs-string">"This buys some time for the villagers to escape."</span>
        end2 = <span class="hljs-string">"Sadly, the ogre king takes over Anya's village."</span>
        end3 = <span class="hljs-string">"She is just thankful that the villagers were able to get to safety."</span>
        end4 = <span class="hljs-string">"The end!"</span>

        textSurface = myFont.render(no1, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">10</span>))
        textSurface = myFont.render(end1, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">24</span>))
        textSurface = myFont.render(end2, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">38</span>))
        textSurface = myFont.render(end3, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">52</span>))
        textSurface = myFont.render(end4, <span class="hljs-literal">True</span>, <span class="hljs-string">"black"</span>)
        screen.blit(textSurface, (<span class="hljs-number">10</span>, <span class="hljs-number">66</span>))


<span class="hljs-comment"># Game loop</span>
<span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
    <span class="hljs-comment"># Checks to see if at beginning of game</span>
    <span class="hljs-keyword">if</span> currentQuestion == <span class="hljs-number">0</span>:
        intro()

    <span class="hljs-comment"># Get the most recent event</span>
    currentEvent = event.poll()

    <span class="hljs-comment"># Displays the correct question based on event that occurs</span>
    <span class="hljs-keyword">if</span> currentEvent.type == KEYDOWN:
        story(currentEvent.key, currentQuestion)
        currentQuestion = currentQuestion + <span class="hljs-number">1</span>

    <span class="hljs-comment"># add text to screen</span>
    display.update()
</code></pre>
<blockquote>
<p>code source: codecombat (developing python game)</p>
</blockquote>
<p>The code above is a simple interactive story game written with Pygame<strong>.</strong> In the first few lines, you import <strong>Pygame</strong> and its display, font, and event modules.</p>
<p><code>pygame.locals</code> brings in constants like <code>K_y</code> (Y key), <code>K_n</code> (N key), and⁣ <code>KEYDOWN</code>.</p>
<p>The preceding line then initializes Pygame and creates a window (<code>screen</code>). It also sets the window title and then loads a font for rendering the text.</p>
<p>Then you have the section for functions that power the story (<code>intro</code>, <code>question1</code>, <code>question2</code>, <code>question3</code>, and conditions based on the player’s answer).</p>
<p>In summary, the code is a choose-your-own-adventure text game with a single character, Anya. The choices of the player determine which text is shown.</p>
<p>To run this script, install <code>pygame</code>.</p>
<pre><code class="lang-bash">sudo apt-get update
sudo apt-get install -y python3-pygame
pip install pygame
</code></pre>
<p>The above code will install <code>pygame</code> into your environment, after which you can then run the script.</p>
<pre><code class="lang-bash">python3 test.py
</code></pre>
<p>When you run this inside Codespaces, the window will appear in the noVNC tab. If it doesn’t open automatically, click on <code>connect</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757340287440/77bafc3f-f3eb-402a-8ce1-9cfe6a739b3c.png" alt="screenshot of the python gui app output" class="image--center mx-auto" width="1332" height="1095" loading="lazy"></p>
<h2 id="heading-tips">Tips</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757340460701/c3c8376a-4b6f-4a05-8ed3-83c036476150.png" alt="ALSA error in codespaces" class="image--center mx-auto" width="1443" height="217" loading="lazy"></p>
<ul>
<li><p><strong>Ignore ALSA errors</strong>: Codespaces doesn’t have sound output, so audio warnings are normal.</p>
</li>
<li><p><strong>Adjust resolution</strong>: Change <code>1024x768x24</code> in the script if you want a bigger (or smaller) screen.</p>
</li>
<li><p><strong>Use with other libraries</strong>: Tkinter, PyQt, and Matplotlib interactive plots. All will work with this setup.</p>
</li>
<li><p><strong>Automate DISPLAY export</strong>: Add <code>export DISPLAY=:1</code> in your bash file if you don’t want to type it each time.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You’ve just turned GitHub Codespaces into a Python GUI environment. By using Xvfb and noVNC, you can run apps that normally require a desktop environment right inside your browser.</p>
<p>Whether you’re building games, testing interfaces, or teaching Python graphics, you can now do it all in Codespaces without leaving the cloud.</p>
<blockquote>
<p>Want to try it yourself? Clone this <a target="_blank" href="https://github.com/CodeLeom/Python-codespaces">repo</a>, run <code>./start-gui.sh</code>, and launch your first GUI app in Codespaces today.</p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ GitHub Codespaces vs Gitpod – Full Stack Development Moves to the Cloud ]]>
                </title>
                <description>
                    <![CDATA[ By Nader Dabit Gitpod and GitHub Codespaces are cloud based developer environments that allow you to spin-up high-performance, automated dev environments in seconds. Over the past few months I have gone down the rabbit hole of cloud-based developer e... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/github-codespaces-vs-gitpod-cloud-based-dev-environments/</link>
                <guid isPermaLink="false">66d46044ffe6b1f641b5fa3a</guid>
                
                    <category>
                        <![CDATA[ Cloud Computing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ codespaces ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Gitpod ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Visual Studio Code ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 30 Aug 2021 17:10:36 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/08/pexels-josh-sorenson-1154504.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Nader Dabit</p>
<p><a target="_blank" href="https://www.gitpod.io/">Gitpod</a> and <a target="_blank" href="https://github.com/features/codespaces">GitHub Codespaces</a> are cloud based developer environments that allow you to spin-up high-performance, automated dev environments in seconds.</p>
<p>Over the past few months I have gone down the rabbit hole of cloud-based developer environments. I'm moving several of my projects to the cloud so that developers can deploy the projects with a single click, like <a target="_blank" href="https://github.com/dabit3/polygon-ethereum-nextjs-marketplace">this full stack NFT marketplace</a>.</p>
<p>This has been especially helpful for me, as a teacher and content creator helping developers learn how to code. Now these developers can deploy the example projects without having to set up their local environments so there's one less hurdle for them if they are just getting started. </p>
<p>It is also an overall productivity and efficiency boost as I don’t have to clone and set up projects anymore locally when making updates. Instead, I can just click a button and it’s ready to go.</p>
<p>In this article I'll share my view on the ecosystem together with a comparison of the two leading options in accomplishing this – GitHub Codespaces and Gitpod.</p>
<p>For transparency, Gitpod is also a sponsor of <a target="_blank" href="https://www.youtube.com/naderdabit">my YouTube channel</a>. That being said, I only choose to accept sponsorships from projects that I already enjoy using myself.</p>
<h2 id="heading-cloud-based-development-this-is-the-way"><strong>Cloud-based Development – This Is the Way</strong></h2>
<p>As developers, we like to automate things. We speed up our own workflows, automate infrastructure and CI/CD pipelines, and even create tools that <a target="_blank" href="https://copilot.github.com/">write code themselves</a>. </p>
<p>If you look at modern software pipelines, there is one area we have not automated: our developer environments. They are still brittle, tied to local machines, and require nerve-wracking set-up and maintenance efforts that distract us from being creative and productive. </p>
<p>Dev environments are a constant source of friction during onboarding and ongoing development (remember your last “works on my machine” discussion).</p>
<p>As a teacher and content creator helping new developers learn how to code, one of the most common issues isn't the tutorial or content itself. Rather, it's the developer's local environment not being set up properly, and it's often not even their fault. </p>
<p>There are countless variances of operating systems and application versions that have to be taken into account.</p>
<p>The pain that comes with local dev environments will only get worse over time: larger workloads, more data, more dependencies, more testing, multi-service and multi-track development are all things that are difficult to account for.</p>
<h2 id="heading-github-codespaces-and-gitpod-lead-the-pack-of-cloud-based-dev-environments"><strong>GitHub Codespaces and Gitpod Lead the Pack of Cloud-based Dev Environments</strong></h2>
<p>Some years ago, Cloud9 moved into the area as a first generation of browser IDEs. Though their ideas were going in the right direction, technology and community just were not ready (yet).</p>
<p>A lot has changed since then. In addition to the advent and meteoric rise of VS Code, there were big leaps in container and VM technology that made it faster, more secure, scalable, and practical to run developer environments in the cloud. </p>
<p>No surprise that we are seeing companies like Google, Facebook, Shopify and most recently GitHub fully moving software development to the cloud with internal solutions.</p>
<p>There are a few players in the area that have taken advantage of those developments – although some might argue that other existing solutions focus more on prototyping and playground work for specific languages and are not a full replacement for local development. </p>
<p>When it comes to cloud-based dev environments that work for day-to-day professional software development, there are two main options: <a target="_blank" href="https://www.gitpod.io/">Gitpod</a> and <a target="_blank" href="https://github.com/features/codespaces">GitHub Codespaces</a>.</p>
<p>So what do they do? Well, essentially they let you spin up <strong>task-based developer environments</strong> in the cloud from any Git context. Once you’re done, you just close them. </p>
<p>This is a huge boost for productivity. Think about multi-track development (no changing of dev environment settings when switching contexts to review pull-requests), onboarding, consistency or just working remotely. You can work from any computer, Chromebook, or tablet.</p>
<p>In this article we will take a look under the hood and assess and evaluate both products according to the following categories:</p>
<ul>
<li>Workflow and Collaboration</li>
<li>IDE</li>
<li>Runtime</li>
<li>Automation</li>
<li>Open Source &amp; Ecosystem</li>
<li>Availability &amp; Pricing</li>
</ul>
<p>Let’s dive into it!</p>
<h2 id="heading-github-codespaces-vs-gitpod-workflow">GitHub Codespaces vs Gitpod Workflow</h2>
<p>GitHub Codespaces and Gitpod are both services that allow you to do exactly the same as what you could do locally on a Linux machine with one major addition: your developer environment can be configured as code and hence is version controlled, reproducible and automatable. </p>
<p>GitHub Codespaces allows you to do that with a <a target="_blank" href="https://code.visualstudio.com/docs/remote/devcontainerjson-reference">devcontainer.json</a> file and Gitpod with a <a target="_blank" href="https://www.gitpod.io/docs/references/gitpod-yml">.gitpod.yml</a> file that you place into your repository (more on that later). Both do essentially the same thing, like define what Docker container to use, what scripts to run, and they control what extensions will be available in your Codespace (GitHub) / workspace (Gitpod). </p>
<p>Both products embrace a software development flow that enables developers to start a developer environment from any Git context (Issue, PR/MR, branches, and so on) with one-click for the specific task you are working on. </p>
<p>This task-based development flow is what ultimately sold me on switching from local dev for real world projects and, after using it, feels like it would be really hard to go back to not having it.</p>
<p>Developer environments turn just into some resource I can spin up on demand and close and forget about if I am done with my task. Gitpod is excelling at that workflow and built their product around it. </p>
<p>Reading the <a target="_blank" href="https://github.blog/2021-08-11-githubs-engineering-team-moved-codespaces/">blog post</a> from the engineering team at GitHub, it feels like they internally adapted a similar workflow, however this is not native with Codespaces right now.</p>
<p><img src="https://lh4.googleusercontent.com/q0xOqarPIMDK9-hcOLujGzXbJsrkFiFyNnGmGSpkqk4u4eKGbnoHmG7cNYQlLtm_58M7rkpZ_dgHuFHyAK6o3V2rL61hfk-r87NsYTPWJS_kLQW_L9LLo0Idwg_7pq-TXh-u9MK3=s0" alt="Image" width="720" height="874" loading="lazy"></p>
<p><img src="https://lh6.googleusercontent.com/8LIlWDgOmEO32gO9JSUYL_5tPKr-W9g3C0mnFTuefYVWpd3ppCI4IVT8ap5jkfb2HuhVcHb3LSqkBcGHQf7wnEFVeyN7Nl5Eph2a9VndnNMlkxQBbeaktYZWJS1RhKERq4tHU9Vg=s0" alt="Image" width="640" height="480" loading="lazy"></p>
<h2 id="heading-collaboration-with-codespaces-vs-gitpod">Collaboration with Codespaces vs Gitpod</h2>
<p>Both GitHub Codespaces and Gitpod offer ways to collaborate, but they differ in their approach. </p>
<p>On both platforms, when your development environment is running, you can expose any TCP port publicly or privately to the internet. This enables workflows where you can share links to a web-server or API server as standard URLs. </p>
<p>Gitpod offers functionality to share a snapshot of the workspace with a co-worker but GitHub Codespaces does not.</p>
<p>GitHub Codespaces offers the ability to interactively pair program when the <a target="_blank" href="https://visualstudio.microsoft.com/services/live-share/">LiveShare extension</a> is installed while Gitpod offers the ability to share the workspace itself with collaborators. </p>
<p>Once Gitpod enables local VS Code support (1-2 weeks from this writing) you can also use LiveShare with Gitpod.</p>
<p>Here are some further resources where you can read more about this.</p>
<ul>
<li><a target="_blank" href="https://www.gitpod.io/blog/i-said-goodbye-to-local-development-and-so-can-you#develop-a-new-feature">https://www.gitpod.io/blog/i-said-goodbye-to-local-development-and-so-can-you#develop-a-new-feature</a></li>
<li><a target="_blank" href="https://github.blog/2021-08-11-githubs-engineering-team-moved-codespaces/">https://github.blog/2021-08-11-githubs-engineering-team-moved-codespaces/</a></li>
<li><a target="_blank" href="https://visualstudio.microsoft.com/services/live-share/">https://visualstudio.microsoft.com/services/live-share/</a></li>
</ul>
<h2 id="heading-gitpod-vs-codespaces-ide">Gitpod vs Codespaces IDE</h2>
<p>Both Gitpod and Codespaces ship upstream, and stock VS Code as their default IDE running in the browser. It feels like, acts like, and is literally the same VS Code that you are used to from your desktop. Be aware of cmd+W however :). </p>
<p>As GitHub is owned by Microsoft, I understand that the VS Code team was heavily involved in building GitHub Codespaces. </p>
<p>The team behind Gitpod has a long background in open-source developer tooling, and they initially created <a target="_blank" href="https://theia-ide.org/">Theia</a> (which is also based on VS Code). |But recently, they switched to stock VS Code and maintain a very lightweight fork of VS Code that has also continued to gain adoption by other teams in the industry (<a target="_blank" href="https://github.com/gitpod-io/vscode/">https://github.com/gitpod-io/vscode/</a>).</p>
<p><img src="https://lh6.googleusercontent.com/F__NabACVugaw59_F56hT_7euuIyGyGo2gUYRo3tpcRWHZRHKQpomawaGJGph2scXTsD14G-PQwy3H71DKWTU0XQs03tJSENU4IeDRxh-lXL0G3_JB1C9CqWIqPxWFhlSQsKRpy1=s0" alt="Image" width="1570" height="1592" loading="lazy"></p>
<p><img src="https://lh3.googleusercontent.com/rIv3ade5u-A027pXxPZ7K-zn--ddFchT3EbjTS-XzYD35jFZ5E-MdefIc3gch2Y5xLvSy6udUuCfWkL-CFZvlvNSkjwrun3MqwjO7ZH98qHrcyQ1HcWm7P7obCqSwVZhulNd1pLS=s0" alt="Image" width="1570" height="1592" loading="lazy"></p>
<h2 id="heading-vs-code-extension-marketplace-for-codespaces-and-gitpod">VS Code Extension Marketplace for Codespaces and Gitpod</h2>
<p>Having the VS Code team behind the product and being able to access all proprietary extensions (like Liveshare, for example) through the Microsoft-controlled Visual Studio Marketplace is a plus for Codespaces. </p>
<p>As a response, Gitpod created <a target="_blank" href="https://open-vsx.org/">https://open-vsx.org/</a> (now hosted under the Eclipse Foundation), which is a vendor-neutral marketplace run by the Eclipse Foundation for VS Code extensions that is accessible through Gitpod. </p>
<p>Though there is almost extension parity for the most popular VS Code extensions, Microsoft’s (excellent) proprietary extensions have not found a way to OpenVSX. </p>
<p>In case you don’t find an open-source extension on OpenVSX, you can trigger the publish automation by sending in a pull-request to <a target="_blank" href="https://github.com/open-vsx/publish-extensions">https://github.com/open-vsx/publish-extensions</a>.</p>
<h3 id="heading-remote-development-from-desktop-vs-code">Remote Development from Desktop VS Code</h3>
<p>I am a big fan of being able to connect from my local Desktop VS Code into a dev environment running on somebody else's computer. </p>
<p>Both products offer that feature, but the flow that Codespaces ships out of the box is superior compared to the approach from Gitpod. </p>
<p>While you can achieve the same with Gitpod’s <a target="_blank" href="https://www.gitpod.io/blog/local-app">local app</a>, the setup involves more work and friction from a user’s perspective. Asking the Gitpod team about this, I received feedback that they will release a similar one-click experience at the end of August.</p>
<h3 id="heading-what-about-other-ides-than-vs-code">What about other IDEs than VS Code?</h3>
<p>For GitHub Codespaces I could not find any information for other IDEs than VS Code. And given that Microsoft is behind both projects, I’d expect that they'll probably focus on VS Code. </p>
<p>In contrast, Gitpod tries to stress that what they have built is, on an architectural level, IDE independent and allows you to run any IDE image you can run remotely in their container. </p>
<p>I found some templates in their GitHub Repo that allow you to run the Jetbrains product fleet (based on <a target="_blank" href="https://github.com/JetBrains/projector-installer">https://github.com/JetBrains/projector-installer</a>). </p>
<p>The developer experience there still feels a bit clunky. Digging a bit deeper I found this interesting <a target="_blank" href="https://youtrack.jetbrains.com/issue/IDEA-226455#focus=Comments-27-5125731.0-0">discussion</a> around one of the most requested features from the Jetbrains community that would enable remote support via SSH out of the box. I would love to see that supported by Gitpod and Codespaces.</p>
<p><img src="https://lh4.googleusercontent.com/rmSR14doieAaSg3SibqyU7LewYPc23SlZ6ntjhnAiczvd2zQZLVgwhlWsQ58z6Ax7Xbw3f0e_aUUQYSv8c6TezMwqMSR3usbAIWEezVerseZuHjLHZl3JBhxZ1JSuXxEucoRnVR_=s0" alt="Image" width="1398" height="1650" loading="lazy"></p>
<p>Here are some resources for further reading:</p>
<ul>
<li><a target="_blank" href="https://www.theregister.com/2021/04/08/gitpod_talks_up_importance_of/">https://www.theregister.com/2021/04/08/gitpod_talks_up_importance_of/</a></li>
<li><a target="_blank" href="https://www.gitpod.io/blog/local-app">https://www.gitpod.io/blog/local-app</a></li>
<li>https://www.gitpod.io/docs/integrations/jetbrains</li>
</ul>
<h2 id="heading-codespaces-vs-gitpod-runtime">Codespaces vs Gitpod Runtime</h2>
<p>GitHub Codespaces runs on virtual machines which come with great isolation out of the box and are easier to provision and manage. However, they also carry the overhead of the full operating system, making them larger and slower to start as well as more costly.</p>
<p>Gitpod runs on lightweight containers that spin up quickly and enjoy a far higher cloud density (as more processes can run in parallel on the same underlying hardware, there is less idle compute). This allows Gitpod workspaces to spin-up faster and be more resource – that is cost and energy – efficient.</p>
<p>The downside of containers is that, by default, they do not have the same isolation/security benefits as virtual machines provide. </p>
<p>Before last year, sudo-rights (and with that docker-in-docker) were not possible in Gitpod workspaces. Earlier this year they implemented namespace isolation features that made both of those things possible (see their <a target="_blank" href="https://www.youtube.com/watch?v=iYLCHQgj0fE&amp;t=274s">head of engineering explaining how they achieved that</a>).</p>
<p>Both Codespaces and Gitpod support docker-in-docker for Docker Compose scenarios and nested virtualization which enables running operating systems or appliances in your browser.</p>
<p>Here are some more resources for you on this:</p>
<ul>
<li><a target="_blank" href="https://www.gitpod.io/blog/root-docker-and-vscode">https://www.gitpod.io/blog/root-docker-and-vscode</a></li>
<li><a target="_blank" href="https://github.com/gitpod-io/template-nixos">https://github.com/gitpod-io/template-nixos</a></li>
</ul>
<h2 id="heading-automation-with-codespaces-and-gitpod">Automation with Codespaces and Gitpod</h2>
<p>Both heavily embrace the notion of dev environment as code that Vagrant first coined and Gitpod then further built out. </p>
<p>The basic idea behind that is applying ideas from Infrastructure as Code to dev environments. Codespaces uses a <a target="_blank" href="https://code.visualstudio.com/docs/remote/devcontainerjson-reference">devcontainer.json</a> format as a configuration file while Gitpod uses a .gitpod.yml.</p>
<p>Given the reach and distribution power of Codespaces and VS Code, my prediction is that the <a target="_blank" href="https://code.visualstudio.com/docs/remote/devcontainerjson-reference">devcontainer.json</a> format will win long-term as the industry standard for configuring developer environments. As listed on their <a target="_blank" href="https://github.com/gitpod-io/roadmap/issues/16">roadmap</a>, Gitpod plans to support that as well. Right now they don’t and run on a <a target="_blank" href="https://www.gitpod.io/docs/references/gitpod-yml">.gitpod.yml</a>.</p>
<p>Creating and setting up your dev-env-as-code is only the first step towards fully automated per-task developer environments. As you do not want to wait for dependencies to download and code to build every time you start a developer environment, the workspaces/codespaces need to be prebuilt before you even start.</p>
<p>Gitpod supports <a target="_blank" href="https://www.gitpod.io/docs/prebuilds">prebuilds</a> for that (think about them as a CI/CD server where Gitpod prebuilds the full workspace / runs the automation on every commit to Git). Automation only works if executed frequently. </p>
<p>Codespaces currently do not have prebuilds included in their GA, but internally they already use them. Therefore it should be a matter of months until they also publicly release that feature.</p>
<p>You can read more here:</p>
<ul>
<li><a target="_blank" href="https://www.gitpod.io/screencasts/continuously-prebuild-your-project">https://www.gitpod.io/screencasts/continuously-prebuild-your-project</a></li>
<li><a target="_blank" href="https://github.blog/2021-08-11-githubs-engineering-team-moved-codespaces/">https://github.blog/2021-08-11-githubs-engineering-team-moved-codespaces/</a></li>
</ul>
<h2 id="heading-codespaces-and-gitpod-open-source-and-ecosystem">Codespaces and Gitpod Open Source and Ecosystem</h2>
<p>The biggest difference between the two is that Gitpod is open source and everyone can contribute to the project. You can self-host it on <a target="_blank" href="https://www.gitpod.io/docs/self-hosted/latest/installation/on-gke">GKE</a>, <a target="_blank" href="https://www.gitpod.io/docs/self-hosted/latest/installation/on-amazon-eks">EKS</a>, and vanilla Kubernetes. </p>
<p>Their roadmap and development work is public and everyone can contribute to the project. In addition to this, maintainers and core contributors to open-source projects <a target="_blank" href="https://www.gitpod.io/docs/professional-open-source">get Gitpod for free</a>.</p>
<p>With GitHub, Microsoft owns the market leading social platform for developers and they integrated GitHub Codespaces as a first-class citizen into the developer experience on GitHub. This means that by default the UI in GitHub shows you an Open in Codespaces button, which nicely embeds into your development workflow. </p>
<p>For Gitpod to achieve the same level of integration you need to download either the <a target="_blank" href="https://www.gitpod.io/docs/browser-extension/">browser extension</a> or a <a target="_blank" href="https://www.gitpod.io/docs/browser-bookmarklet">bookmarklet</a>. GitLab has a <a target="_blank" href="https://about.gitlab.com/blog/2021/07/19/teams-gitpod-integration-gitlab-speed-up-development/">strategic partnership</a> with Gitpod and has on every repository and merge request an “Open in Gitpod” button built into the GitLab UI.</p>
<p>Contrary to Microsoft, Gitpod follows a strategy where it is neutral by default, not owned by big tech and designed in a way to integrate with whatever tooling developers want to use. </p>
<p>This means it not only works with GitHub but also other Git providers such as GitLab and Bitbucket and you can deploy it on your own infrastructure.</p>
<h2 id="heading-availability-pricing-and-specs-of-codespaces-vs-gitpod">Availability, Pricing, and Specs of Codespaces vs Gitpod</h2>
<p>Gitpod has been available for more than 2.5 years, while GitHub Codespaces came out of beta on the 11th of August 2021 for customers with a GitHub Team or GitHub Enterprise subscription. </p>
<p>Based <a target="_blank" href="https://twitter.com/natfriedman/status/1425508910476271624?s=20">on a tweet</a> from their CEO, Nat Friedman, we can expect that individual developers will have access to GitHub Codespaces at the end of the year.</p>
<p>GitHub Codespaces is currently free for all organizations on a GitHub Team or GitHub Enterprise subscription until September 10th. The billing increment is for the amount of minutes a workspace is active, and for the amount of storage used on disk for each workspace until a user deletes the workspace.</p>
<p>You can <a target="_blank" href="https://docs.github.com/en/codespaces/codespaces-reference/understanding-billing-for-codespaces">read more about that here</a>. </p>
<p>Gitpod is free for public and private repositories for 50 hours per month. Maintainers and core contributors of well-established open-source projects can apply for a voucher that upgrades their account to unlimited hours per month.</p>
<p>Read more about Gitpod pricing in these resources:</p>
<ul>
<li><a target="_blank" href="https://www.gitpod.io/blog/cloud-based-development-for-everyone">https://www.gitpod.io/blog/cloud-based-development-for-everyone</a></li>
<li><a target="_blank" href="https://www.gitpod.io/pricing">https://www.gitpod.io/pricing</a></li>
<li><a target="_blank" href="https://www.gitpod.io/docs/professional-open-source">https://www.gitpod.io/docs/professional-open-source</a></li>
</ul>
<p>To simplify comparing the offerings from GitHub Codespaces and Gitpod, here are three different scenarios using the same amounts of CPU, memory, and storage for each use case.  </p>
<table><colgroup><col><col><col><col></colgroup><tbody><tr><td><br></td><td><p><span>Product Manager</span></p></td><td><p><span>Developer</span></p></td><td><p><span>Power Developer</span></p></td></tr><tr><td><p><span>Working hours</span></p></td><td><p><span>2h per day, 21 working days per month</span></p></td><td><p><span>5h per day, 21 working days per month</span></p></td><td><p><span>10h per day, 21 working days per month.</span></p></td></tr><tr><td><p><span>Total Hours per month</span></p></td><td><p><span>42 hours</span></p></td><td><p><span>105 hours</span></p></td><td><p><span>210 hours</span></p></td></tr><tr><td><p><span>Amount&nbsp; of CPUs</span></p></td><td><p><span>8 cores</span></p></td><td><p><span>8 cores</span></p></td><td><p><span>8 cores</span></p></td></tr><tr><td><p><span>Amount of Memory</span></p></td><td><p><span>12GB</span></p></td><td><p><span>12GB</span></p></td><td><p><span>12GB</span></p></td></tr><tr><td><p><span>Amount of Storage</span></p></td><td><p><span>64Gb</span></p></td><td><p><span>64Gb</span></p></td><td><p><span>64Gb</span></p></td></tr><tr><td><br></td><td><br></td><td><br></td><td><br></td></tr><tr><td><p><span>Total Cost on GitHub Codepsaces</span></p></td><td><p><span>$30.24 USD/month compute and $2.24 USD/month in additional storage fees (first 32GB per workspace is free)</span></p></td><td><p><span>$75.6 USD/month compute and $2.24 USD/month in additional storage fees (first 32GB per workspace is free)</span></p></td><td><p><span>$151.2 USD/month compute and $2.24 USD/month in additional storage fees (first 32GB per workspace is free)</span></p></td></tr><tr><td><p><span>Total Cost on Gitpod</span></p></td><td><p><span>$9 USD/month</span></p></td><td><p><span>$25 USD/month</span></p></td><td><p><span>$39 USD/month</span></p></td></tr></tbody></table>

<p>The amount of CPU and memory for each workspace launched is configurable in GitHub Codespaces and they offer SKUs of up to 32 CPU cores and 64GB of RAM. Gitpod at this time does not yet offer a way to have more or less compute resources.</p>
<h2 id="heading-see-it-in-action"><strong>See it in action</strong></h2>
<p>I hope you’re as excited as I am after first hearing about the concept of dev environments as code in the cloud! Give both a try and see for yourself how you like them.  </p>
<p>Right now I prefer Gitpod as it’s free for my use cases, has pre-builds, is accessible to anyone who wants to use it, is open source, and can be used with any Git provider including GitHub.</p>
<h3 id="heading-how-to-get-started-with-gitpodhttpgitpodio">How to Get Started with <a target="_blank" href="http://gitpod.io">Gitpod</a>:</h3>
<ul>
<li>Prefix any GitLab, GitHub or Bitbucket URL with gitpod.io/# to dive right in</li>
<li>Or use their <a target="_blank" href="https://www.gitpod.io/docs/browser-extension/">browser extension</a> or <a target="_blank" href="https://www.gitpod.io/docs/browser-bookmarklet">browser bookmarklet</a> for starting workspaces from any git context</li>
<li>Or try their <a target="_blank" href="https://github.com/gitpod-io?q=template-">quickstart templates</a></li>
<li>Check out my guides <a target="_blank" href="https://www.youtube.com/watch?v=tXSF7lIQouQ">here</a> and <a target="_blank" href="https://www.youtube.com/watch?v=hUSzdIOrlY4">here</a></li>
</ul>
<h3 id="heading-how-to-get-started-with-codespaceshttpsgithubcomfeaturescodespaces">How to Get Started with <a target="_blank" href="https://github.com/features/codespaces">Codespaces</a>:</h3>
<ul>
<li>If you’re a GitHub Teams or Enterprise customer, look for an “Open in GitHub” button next to a repo</li>
<li>Individual developers need to wait until it launches more widely</li>
<li>Check out <a target="_blank" href="https://www.youtube.com/watch?v=dMs-8QY1URw">this</a> video for an overview.</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How GitHub Codespaces Can Increase Productivity and Lower Barriers ]]>
                </title>
                <description>
                    <![CDATA[ In this article, we'll take a look at how GitHub Codespaces can help remove barriers for new teammates and contributors. The most recent integration between Visual Studio Code and GitHub really helps make development accessible and welcoming. Now in ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-github-codespaces-increase-productivity-and-lower-barriers/</link>
                <guid isPermaLink="false">66bd8f32ffb0fc5947cc912a</guid>
                
                    <category>
                        <![CDATA[ codespaces ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Victoria Drake ]]>
                </dc:creator>
                <pubDate>Tue, 18 Aug 2020 15:36:06 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/08/cover-2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, we'll take a look at how GitHub Codespaces can help remove barriers for new teammates and contributors.</p>
<p>The most recent integration between Visual Studio Code and GitHub really helps make development accessible and welcoming.</p>
<p>Now in beta, <a target="_blank" href="https://docs.github.com/en/github/developing-online-with-codespaces/about-codespaces">GitHub Codespaces</a> provide an online, in-the-browser IDE powered by Visual Studio Code.  </p>
<p>This lets you use this full-featured IDE, complete with extensions, terminal, Git commands, and all the settings you’re accustomed to, on any machine. You can now bring your development workflow anywhere using a tablet or other browser-based device.</p>
<p>Codespaces is great news for open source contributors, too. <a target="_blank" href="https://docs.github.com/en/github/developing-online-with-codespaces/configuring-codespaces-for-your-project">Adding a codespace configuration</a> to your project is a great way to invite new folks to easily start contributing. </p>
<p>A new open source contributor or new hire at your organization can quickly fire up a codespace and get hacking on a <code>good first issue</code> with no local environment set up or installations necessary.</p>
<p><img src="https://victoria.dev/blog/add-productivity-remove-barriers-with-github-codespaces/open-with-codespaces-button.png" alt="Starting a new codespace" width="600" height="400" loading="lazy"></p>
<p>We’ve added codespace configuration settings over at the <a target="_blank" href="https://github.com/OWASP/wstg">OWASP Web Security Testing Guide (WSTG)</a>. Want to take it for a spin? See our <a target="_blank" href="https://github.com/OWASP/wstg/issues">open issues</a>.</p>
<h2 id="heading-configuring-codespaces">Configuring Codespaces</h2>
<p>You can use Visual Studio Code’s <code>.devcontainer</code> folder to configure a development container for your repository as well. </p>
<p>Many <a target="_blank" href="https://github.com/microsoft/vscode-dev-containers/tree/master/containers">pre-built containers are available</a> – just copy the <code>.devcontainer</code> you need to your repository root. If your repository doesn’t have one, a <a target="_blank" href="https://github.com/microsoft/vscode-dev-containers/tree/master/containers/codespaces-linux">default base Linux image</a> will be used.</p>
<p>Here’s a reason to remove <code>.vscode</code> from your <code>.gitignore</code> file. Any new codespaces created in your repository will now respect settings found at <code>.vscode/settings.json</code>.  This means that your online IDE can have the same Workspace configuration as you have on your local machine. Isn’t that useful!</p>
<h2 id="heading-making-codespaces-personal">Making Codespaces Personal</h2>
<p>For next-level <a target="_blank" href="https://docs.github.com/en/github/developing-online-with-codespaces/personalizing-codespaces-for-your-account">dotfiles personalization</a>, consider committing relevant files from your local <code>dotfiles</code> folder as a public GitHub repository at <code>yourusername/dotfiles</code>. </p>
<p>When you create a new codespace, this brings in your configurations, such as shell aliases and preferences, by creating symlinks to dotfiles in your codespace <code>$HOME</code>. This personalizes all the codespaces you create in your account. </p>
<p>Need some inspiration? Browse <a target="_blank" href="https://github.com/victoriadrake/dotfiles">my dotfiles repository on GitHub</a>.</p>
<h2 id="heading-developing-in-codespaces">Developing in Codespaces</h2>
<p><a target="_blank" href="https://docs.github.com/en/github/developing-online-with-codespaces/developing-in-a-codespace">Developing in a codespace</a> is a familiar experience for Visual Studio Code users, right down to running an application locally. </p>
<p>Thanks to <a target="_blank" href="https://docs.github.com/en/github/developing-online-with-codespaces/developing-in-a-codespace">port forwarding</a>, when I run an application in a codespace terminal, clicking on the resulting <code>localhost</code> URL takes me to the appropriate port as output from my codespace. </p>
<p>When I’m working on <a target="_blank" href="https://victoria.dev/">my blog</a> in my codespace, for example, I run <code>hugo serve</code> then click the provided <code>localhost:1313</code> link to see a preview of my changes in another browser tab.</p>
<p>Want to stay in sync between devices? There’s an extension for that. You can <a target="_blank" href="https://docs.github.com/en/github/developing-online-with-codespaces/connecting-to-your-codespace-from-visual-studio-code">connect to your codespace from Visual Studio Code</a> on your local machine so you can always pick up right where you left off.</p>
<h2 id="heading-develop-anywhere">Develop Anywhere</h2>
<p>Codespaces is a super exciting addition to my GitHub workflow. It allows me to access my full development process pretty much anywhere, using devices like my iPad. </p>
<p>It’ll also make it easier for new open source contributors or new hires at your organization to hit the ground running with a set-up IDE. </p>
<p>If you have access to the limited beta, I invite you to spin up a codespace and try <a target="_blank" href="https://github.com/OWASP/wstg/issues">contributing to the WSTG</a>, or to <a target="_blank" href="https://github.com/users/victoriadrake/projects/1">an issue on one of my open source projects</a>.</p>
<p>I’m looking forward to general availability and seeing what the open source community will dream up for GitHub Codespaces next!</p>
<p>And yes – codespaces support <a target="_blank" href="https://github.com/victoriadrake/kabukicho-vscode">your favorite Visual Studio Code theme</a>. ?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/codespace.png" alt="Image" width="600" height="400" loading="lazy">
<em>Screenshot of a codespace with the [Kabukichō](https://marketplace.visualstudio.com/items?itemName=VictoriaDrake.kabukicho" rel="noopener) theme for Visual Studio Code</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ GitHub Codespaces – How to Code Right in Your Browser with Your Own Cloud Dev Environment ]]>
                </title>
                <description>
                    <![CDATA[ GitHub Codespaces enable you to experiment with complex software development stacks right from the web browser. No software to install or configure. No stress. No mess. A gif showing the setup process of a GitHub Codespace In the recent GitHub Satel... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-programming-in-your-browser-the-right-way/</link>
                <guid isPermaLink="false">66d4604a264384a65d5a95ac</guid>
                
                    <category>
                        <![CDATA[ codespaces ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ node js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rust ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Visual Studio Code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WebAssembly ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Michael Yuan ]]>
                </dc:creator>
                <pubDate>Tue, 09 Jun 2020 21:34:29 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9a61740569d1a4ca2547.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>GitHub Codespaces enable you to experiment with complex software development stacks right from the web browser. No software to install or configure. No stress. No mess.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/SSVM-edited-without-music-1-1.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>A gif showing the setup process of a GitHub Codespace</em></p>
<p>In the recent GitHub Satellite online conference, one of the most exciting product announcements was GitHub Codespaces. The idea is to have a code button on every repository.</p>
<p>When you click on it, it launches a fully featured VSCode IDE with all the necessarily software dependencies, including operating system level libraries, to build and run the project. This VSCode IDE runs entirely in your browser, and will not install any software or change any configuration to mess up your computer.</p>
<p>Sounds too good to be true? Well, watch the Github Satellite keynote segment about Codespaces yourself!</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/fQbH3meWNQ8" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>A key benefit of Github Codespaces is how quickly you can on-board new developers to a project. A new developer can get set up in minutes, instead of days, and immediately start contributing to the project. It is a great learning tool for new languages, frameworks, and software tools.</p>
<p>Under the hood, it starts a Docker container on a remote server, installs the entire software stack required by the project, and runs tasks like compiling and debugging in the remote Docker.</p>
<p>The web browser acts as a front end UI for the Docker instance. This approach requires no software install on the developer’s machine. But the trade-off is that all software installation from the operation system all the way to the final application happens on the server.</p>
<p>GitHub must start a fresh server for each Codespaces instance. That requires a lot of data center resources. In fact, the <a target="_blank" href="https://github.com/features/codespaces/">GitHub Codespaces web page</a> has a waiting list as of today (June 2020).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/codespaces-beta.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Personally, I cannot wait for GitHub Codespaces to become available. But a time machine does exist. You can experience all the features in GitHub Codespaces today, for free.</p>
<h2 id="heading-vs-codespaces">VS Codespaces</h2>
<p>The software behind GitHub Codespaces is actually based on a Microsoft VSCode product called <a target="_blank" href="https://online.visualstudio.com/">VS Codespaces</a>. VS Codespaces is available today to all Microsoft Azure users. And yes, it allows you to open GitHub repositories in VSCode IDE directly from a browser window.</p>
<p>In this tutorial, I will show you how to use Codespaces in your own development work today.</p>
<p>To make Codespaces available in your GitHub repositories, you just need to add the following HTML button anywhere on your web pages.</p>
<p>When an Azure user clicks on the button, it asks the user to log into VS Codespaces and walks the user through opening the repository in the online IDE. You can see how it works in the examples in the next section.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://online.visualstudio.com/environments/new?name=My%20Project&amp;repo=username/reponame"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://img.shields.io/endpoint?style=social&amp;url=https%3A%2F%2Faka.ms%2Fvso-badge"</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
</code></pre>
<blockquote>
<p>VS Codespaces runs entirely in your browser and costs around $1 per work day. It is cheaper than a cup of coffee in the office.</p>
</blockquote>
<h2 id="heading-examples">Examples</h2>
<p>Now, let's look into several examples of how you might learn new programming skills using VS Codespaces.</p>
<p>Rust is one of the fastest growing programming languages today. It is voted as the most beloved programming language by Stackoverflow users four years in a row.</p>
<p>But to experiment with Rust requires a complex toolchain of compiler, linker, package manager, tool manager and so on.</p>
<p>VS Codespaces provides an easy way to <a target="_blank" href="https://www.secondstate.io/articles/how-to-learn-rust-without-installing-any-software/">learn Rust</a>. Just click on the VS Codespaces button in <a target="_blank" href="https://github.com/second-state/learn-rust-with-github-actions">this repository</a> and you now have a working Rust project to experiment with!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/learn-rust-20-seconds.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://github.com/second-state/learn-rust-with-github-actions"><em>https://github.com/second-state/learn-rust-with-github-actions</em></a></p>
<p>As a system language, Rust is well positioned to build high performance server side applications. The most promising stack is to compile and run Rust functions in a WebAssembly container, and then access those high performance functions from an existing web application framework, such as Node.js.</p>
<p>However, as you can already see, this “best practice” setup requires a complex stack of software.</p>
<p>Clicking on the VS Codespaces button in <a target="_blank" href="https://github.com/second-state/ssvm-nodejs-starter">this repository</a> gives you a fully functional Node.js project that uses <a target="_blank" href="https://www.secondstate.io/articles/getting-started-with-rust-function/">Rust functions in WebAssembly</a> as modules. You can immediately start to modify the Rust and JavaScript code and run the Node.js application from inside the web browser IDE.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/SSVM-edited-without-music.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://github.com/second-state/ssvm-nodejs-starter"><em>https://github.com/second-state/ssvm-nodejs-starter</em></a></p>
<p><a target="_blank" href="https://www.secondstate.io/articles/why-webassembly-server/">Server-side Rust and WebAssembly</a> sound cool. But do we actually have a more complete example that demonstrate the power and performance of Rust beyond a simple hello world?</p>
<p><a target="_blank" href="https://github.com/second-state/rust-wasm-ai-demo">This repository</a> is such an example. Open it in VS Codespaces and you will have a project for a <a target="_blank" href="https://www.secondstate.io/articles/artificial-intelligence/">Rust + JavaScript app that utilizes Tensorflow to perform image recognition</a>. Since the app runs inside Node.js, it provides a template for AI-as-a-Service web applications.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/06/68747470733a2f2f626c6f672e7365636f6e6473746174652e696f2f696d616765732f414961617325323033307365636f6e64732e676966.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://github.com/second-state/rust-wasm-ai-demo"><em>https://github.com/second-state/rust-wasm-ai-demo</em></a></p>
<p>What if you want to stay on the bleeding edge and use Rust-based web runtime Deno instead of the C-based Node.js? Well, there is a VS Codespaces <a target="_blank" href="https://github.com/anthonychu/azure-functions-deno-worker">template for running Deno as an Azure Function</a> too!</p>
<h2 id="heading-how-it-works">How it works</h2>
<p>If you look closely, each VS Codespaces-enabled repository has a <code>.devcontainer</code> folder. Inside that folder, the <code>Dockerfile</code> specifies how to build the Docker container for the development environment.</p>
<p>For example, the Node.js Docker container is based on Ubuntu Linux with Node.js and selected NPM packages pre-installed. <a target="_blank" href="https://github.com/second-state/ssvm-nodejs-starter/tree/master/.devcontainer">Check out an example here</a>.</p>
<p>The <code>devcontainer.json</code> file specifies the configuration for the VSCode IDE on the remote Docker. For example, it configures the VSCode extensions to install, the terminal and debugger commands to use, and the host ports to forward to for testing and debugging.</p>
<p>Microsoft provides <a target="_blank" href="https://github.com/microsoft/vscode-dev-containers">quite a few <code>.devcontainer</code> templates</a> for you to modify and use. They cover most of the common software development stacks today.</p>
<p>You could further customize the user’s VSCode experience by providing launch and tasks definitions in the <code>.vscode</code> folder. <a target="_blank" href="https://github.com/second-state/ssvm-nodejs-starter/tree/master/.vscode">Check them out</a>!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>With VS Codespaces, and GitHub Codespaces when it launches, the barriers and friction for software development are further reduced. You can get started with complex software stacks without leaving your web browser. <a target="_blank" href="https://www.secondstate.io/articles/getting-started-rust-nodejs-vscode/">Try it today</a>!</p>
<p>Finally, watch the full length GitHub Satellite presentation on GitHub Codespaces.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/dy2eYaNxaQc" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p><a target="_blank" href="https://webassemblytoday.substack.com/">Subscribe to my newsletter</a> and stay in touch.</p>
<div class="embed-wrapper"><iframe src="https://webassemblytoday.substack.com/embed" width="480" height="320" style="border:1px solid #EEE;background:white" title="Embedded content" loading="lazy"></iframe></div> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Top 8 Things I Learned From 4000 Rust Developers ]]>
                </title>
                <description>
                    <![CDATA[ Do you know that most Rust programmers are working on web applications? ? Rust is challenging, but also rewarding and great fun! Learn Rust by example, or ?open this GitHub repo to get started in VSCode. Rust is one of the hottest ? programming langu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/8-things-i-learned-from-4000-rust-developers/</link>
                <guid isPermaLink="false">66d460404bc8f441cb6df811</guid>
                
                    <category>
                        <![CDATA[ codespaces ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programming languages ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Rust ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Visual Studio Code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Applications ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WebAssembly ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Michael Yuan ]]>
                </dc:creator>
                <pubDate>Sun, 24 May 2020 17:57:05 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/05/learn-rust-20-seconds-1.gif" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Do you know that most Rust programmers are working on web applications? ? Rust is challenging, but also rewarding and great fun! Learn <a target="_blank" href="https://rust-by-example-ext.com/">Rust by example</a>, or ?open <a target="_blank" href="https://github.com/second-state/learn-rust-with-github-actions">this GitHub repo</a> to get started in VSCode.</p>
<p>Rust is one of the hottest ? programming languages today. It is StackOverflow's <a target="_blank" href="https://stackoverflow.blog/2020/01/20/what-is-rust-and-why-is-it-so-popular/">most beloved programming language</a> for the past 4 years. Yet, it still has a reputation as the programming language for alpha geeks.</p>
<p>By <a target="_blank" href="https://s3-eu-west-1.amazonaws.com/vm-blog/uploads/2020/04/DE18-SoN-Digital-.pdf">some estimate</a>, there are 600,000 Rust developers world-wide, which is a significant number. But it's still dwarfed when compared with tens of millions of JavaScript, Java, and Python developers.</p>
<p>Who are those Rust developers? What are they using Rust for? Why do they love Rust so much? And most important, how do you join their ranks and see for yourself why Rust is so beloved? Don't get left behind.</p>
<p>In order to answer those questions, the Rust community has conducted annual developer surveys from rust-lang.org since 2016. The site recently released its <a target="_blank" href="https://blog.rust-lang.org/2020/04/17/Rust-survey-2019.html">2019 survey results</a> based on responses from nearly 4000 Rust developers. Here are the top 8 things I learned from the survey.</p>
<h2 id="heading-rust-is-for-professional-programmers">??‍? Rust is for professional programmers</h2>
<p>The Rust programming language is not designed to be “<a target="_blank" href="https://www.secondstate.io/articles/a-rusty-hello-world/">easy to get started</a>”. Rather, it is designed to be powerful and safe at the same time. It aims to be the developer productivity language for professional programmers. It is challenging, fun, and rewarding. That shows in the survey.</p>
<p>Very few respondents call themselves as Rust experts. Most people rate their Rust expertise as 7/10 or below, despite the fact that over 68% of them write Rust code on a weekly basis. It is clearly a language that takes time to master and excel.</p>
<blockquote>
<p>About 37% of Rust users felt productive in Rust in less than a month of use - this is not too different from the percentage last year (40%). Over 70% felt productive in their first year. Unfortunately, like last year, there is still a struggle among users - 21% indicated they did not yet feel productive.</p>
</blockquote>
<p>At the same time, when asked why not using Rust on some projects, the learning curve is cited as the #2 most common reason. The #1 reason, of course, is the company’s decision whether to use a particular programming language in a project.</p>
<h2 id="heading-documentation-is-critical-for-adoption">? Documentation is critical for adoption</h2>
<p>How do developers overcome Rust's learning curve and fall in love with it? Well, not unexpectedly, most developers cited “better documentation” as the driver for adoption.</p>
<p>But true to “professional programmers”, the most sought after Rust documentation is intermediate-level content that helps developers improve their Rust skills and productivity.</p>
<p>While the survey is biased toward developers who already knew the basics of Rust, it seems that there is a thirst for knowledge and self-improvement in this crowd.</p>
<h2 id="heading-developers-do-not-want-tomes-of-text">? Developers do not want tomes of text</h2>
<p>Traditional software documentation typically consists of entire books and websites. New generations of developers want more and better documentation. As a “new” language, Rust is already leading the innovation when it comes to programming language documentation.</p>
<p>For example, the Rust compiler is a self-documenting tool. One of the most unique and beloved features of Rust is its aggressive compiler that helps you ensure correctness and safety before the program even runs. As a result, Rust developers can write highly performant yet safe programs.</p>
<p>When you encounter a compiling error in Rust, the compiler gives you an immediate explanation of the error, and suggestions on how to fix the error based on the context of your program.</p>
<p><a target="_blank" href="https://github.com/second-state/learn-rust-with-github-actions">This starter project</a> in GitHub gets you started with the Rust compiler and the Cargo system without having to install any software toolchain. You can use the VSCode online IDE directly with this project.</p>
<p>Rust documentation web sites like <a target="_blank" href="http://docs.rs">docs.rs</a> and <a target="_blank" href="https://doc.rust-lang.org/rust-by-example/">Rust by Example</a> (and its <a target="_blank" href="https://rust-by-example-ext.com/">Extended Edition</a>) use the <a target="_blank" href="https://play.rust-lang.org/">Rust Playground</a> to run Rust example code directly from the browser. Those interactive books are much better than simple text.</p>
<p>However, as the survey finds out, developers want more. Developers are thirsty for more video content, for example. We can look forward to more coding videos and live broadcasts from the community soon.</p>
<h2 id="heading-most-people-use-rust-for-web-apps-srsly">?️ Most people use Rust for web apps, srsly!</h2>
<p>As a system-level language intended to replace C and C++, most people assume that Rust would be used in infrastructure programming, such as operating systems, native libraries, and runtime platforms.</p>
<p>Yet, the survey clearly shows that by a large margin, most Rust developers today are working on web app backends. No wonder crates like <a target="_blank" href="https://docs.rs/hyper/0.13.5/hyper/">hyper</a>, <a target="_blank" href="https://github.com/actix/actix-web">actix-web</a>, and <a target="_blank" href="https://rocket.rs/">Rocket</a> are among the most popular with Rust developers.</p>
<p>To be sure, most software developers are working on web applications. It is not surprising that, as Rust gains mainstream adoption, Rust projects will mirror the bigger software industry.</p>
<p>However, that does present opportunities for projects and tools that integrates Rust into popular web application runtimes. For example, the <a target="_blank" href="https://www.secondstate.io/articles/getting-started-with-rust-function/">Rust + JavaScript hybrid application</a> approach is gaining momentum.</p>
<h2 id="heading-blockchain-is-a-rusty-hotbed">? Blockchain is a Rusty hotbed</h2>
<p>When it comes to infrastructure software, Rust really shines as a programming language for blockchain systems.</p>
<p>For all software related industry sectors, the survey shows that blockchain only ranks the 35th for all software developers, but 11th for Rust developers. That is in no small part due to aggressive Rust adoption by large blockchain projects such as <a target="_blank" href="https://www.parity.io/">Polkadot / Substrate</a>, <a target="_blank" href="https://www.oasislabs.com/">Oasis</a>, <a target="_blank" href="https://solana.com/">Solana</a>, and <a target="_blank" href="https://www.secondstate.io/">Second State</a> etc.</p>
<p>In many ways, blockchains are perfect fit for Rust. Blockchains represent the community effort to re-build the internet infrastructure in a decentralized manner. They require high performance software that is also very safe. If you are interested in a career as a blockchain engineer, Rust is a must-have skill today.</p>
<h2 id="heading-rust-webassembly">Rust ❤️ WebAssembly</h2>
<p>The survey reveals that WebAssembly is a popular runtime environment for Rust programs. Rust and WebAssembly were both invented at Mozilla.</p>
<p>Rust is focused on performance and memory safety, while WebAssembly is focused on performance and runtime safety. As a runtime container, WebAssembly also makes Rust programs cross-platform and more manageable. There are indeed a lot of synergy between the two technologies.</p>
<p>WebAssembly was originally invented as a client side virtual machine to run in-browser applications. But as Java and JavaScript before it, WebAssembly is now making the migration from the client side <a target="_blank" href="https://www.secondstate.io/articles/why-webassembly-server/">to the server side</a>.</p>
<p>Rust-in-WebAssembly bodes well with the trend of accelerating Rust adoption on backend web applications. You can get started with Rust and WebAssembly application development from a starter project in <a target="_blank" href="https://github.com/second-state/ssvm-nodejs-starter">this GitHub repository</a>.</p>
<h2 id="heading-asynchronous-programming-is-taking-off">? Asynchronous programming is taking off</h2>
<p>In recent years, two new programming languages have gained significant traction among developers. One is Rust, and the other is Go. A big part of their success is their superior support for concurrency programming models.</p>
<p>In fact, an early tagline of Rust is "fearless concurrency". It promises developer productivity in writing asynchronous multi-threaded programs optimized for today’s multi-core CPU architectures. As Node.js demonstrated, easy asynchronous programming is crucial for a language or framework’s success on the server side.</p>
<p>The survey shows that 4 of the 10 most important Rust crates (ie third party libraries), <a target="_blank" href="https://tokio.rs/">tokio</a>, <a target="_blank" href="https://docs.rs/crate/async-std/1.4.0">async</a>, <a target="_blank" href="https://docs.rs/futures/0.3.4/futures/">futures</a>, and <a target="_blank" href="https://hyper.rs/">hyper</a>, are frameworks for asynchronous multi-thread applications.</p>
<h2 id="heading-r-python-and-javascript">? R, Python, and JavaScript</h2>
<p>As the adoption of Rust grows, developers increasingly need to integrate Rust programs with programs written in other languages. In the past, C and C++ were the most common languages to “talk” to Rust as they are all used in infrastructure software projects.</p>
<p>As Rust grows into application software projects, more language level interfaces and bridges are needed now. A good example is the <a target="_blank" href="https://www.secondstate.io/articles/rust-functions-in-nodejs/">Rust JavaScript bridge</a> that supports <a target="_blank" href="https://www.secondstate.io/articles/getting-started-with-rust-function/">Rust functions in Node.js</a> applications.</p>
<p>The survey found that, besides C/C++ and JavaScript, Rust developers are interested in integrating with R and Python. That indicates developer interests in machine learning, big data, and artificial intelligence (AI) applications. In fact, many Python and R machine learning and statistical packages are implemented in native binary modules.</p>
<p>Rust is one of the best programming languages to write native modules. <a target="_blank" href="https://github.com/second-state/rust-wasm-ai-demo">This example</a> shows how to use <a target="_blank" href="https://www.secondstate.io/articles/artificial-intelligence/">Rust to execute Tensorflow models in a Node.js</a> application. In the future, we envision such Rust modules to run in high performance managed containers such as WebAssembly.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>2019 was a year of growth and incremental improvements for Rust. As Rust becomes a mainstream programming language, we look forward to more documentation, more tools, more ecosystem support, more interoperability with other languages, and a gentler learning curve.</p>
<p>And most important of all, we are eager to make more friends and have fun with the most beloved programming language in the world!</p>
<h2 id="heading-about-the-author">About the author</h2>
<p>Dr. Michael Yuan is the <a target="_blank" href="http://www.michaelyuan.com/">author of 5 books</a> on software engineering. His latest book <a target="_blank" href="https://www.buildingblockchainapps.com/">Building Blockchain Apps</a> was published by Addison-Wesley in Dec 2019. Dr. Yuan is the co-founder of <a target="_blank" href="https://www.secondstate.io/">Second State</a>, a VC-funded startup that brings WebAssembly and Rust technologies to <a target="_blank" href="https://www.secondstate.io/articles/why-webassembly-server/">cloud</a>, <a target="_blank" href="https://docs.secondstate.io/">blockchain</a>, and <a target="_blank" href="https://github.com/second-state/rust-wasm-ai-demo/blob/master/README.md">AI</a> applications. It enables developers to deploy fast, safe, portable, and serverless <a target="_blank" href="https://www.secondstate.io/articles/getting-started-with-rust-function/">Rust functions on Node.js</a>.</p>
<div class="embed-wrapper"><iframe src="https://webassemblytoday.substack.com/embed" width="480" height="320" style="border:1px solid #EEE;background:white" title="Embedded content" loading="lazy"></iframe></div>

<p>Prior to Second State, Dr. Yuan was a long time open source contributor at Red Hat, JBoss, and Mozilla. Outside of software, Dr. Yuan is a Principal Investigator at the National Institutes of Health, with multiple research awards on cancer and public health research. He holds a PhD in astrophysics from the University of Texas at Austin.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
