How to run a frontend workshop in Codespaces

Use Codespaces to teach HTML, CSS, and JavaScript to beginner developers

Since 2018, Ive taught introductory web development to cohorts of 15-25 folks. This was a rewarding experience for me. Fun fact: both of my parents were teachers and actually taught at my elementary school, which made me swear off ever becoming a teacher. Ironically, my career is centered around teaching people about technology.

My experience has taught me that when you dont have the right technologies, frustration builds up for both teachers and learners. For example, when I taught folks HTML, CSS, and JavaScript, we always spent the first 15 minutes of each class session making sure all attendees had access to the starter code, could run the code locally, and could follow along.

Further complicating the matter was that these learners were remote and had never written code, so its hard to tell if each person had properly cloned the repository and used the right file.

Sometimes, I would tell them just to copy and paste the contents of each file from the starter code, but that would also present issues. Learners would put them in the wrong files or fail to use the right extensions. It was a mess, but understandably so! When I first learned to code, I had similar experiences. I would attend workshops and spend the whole time trying to set up my environment. Meanwhile, people around me were creating masterpieces.

I finally found the solution to the chaos of workshopping and educating beginner developers to code Github Codespaces.

Why Codespaces is an optimal solution

Running a workshop in Codespaces creates a better experience for all participants. Instead of expecting beginner developers to understand how to clone repositories to work with a template, they can open up a Codespace and work in a development environment I created. Now, I have the peace of mind that everyone has the same environment as me and can easily follow along. This reduces tons of time, stress, and chaos. As a workshop attendee, struggling to follow along in workshops sometimes fractures my ego or makes me lose interest. With Codespaces, the participants can confidently follow along and productively learn.

The experience for each workshop attendee

The experience I created for each participant resembles the following:

  • The participant opens a Codespace, and it immediately loads with the extensions I require:
    • ESLint – This helps learners quickly recognize and reduce any issues in their code
    • Prettier – This helps learners format their code in a way that is easy to read and follow
    • Live Share – Learners can use this to collaborate and pair program with each other.
    • Deploy to GitHub Pages – This is an extension I developed to help folks quickly deploy their static sites to GitHub Pages. This extension reduces the extra steps I would need to guide learners into configuring GitHub Pages. Instead, its a few button clicks, and they can stay within their IDE. Read this blog post to learn how to use the extension, and check out this blog post to learn how I created the extension.
    • Panda Theme – While its unnecessary, beginner developers tend to focus on accuracy. They want to memorize every method, and they sometimes feel uncertain when the session theyre following has a different color syntax highlighting. Multiple times, learners have expressed concern that they possibly mistyped something because my variables are pink, but their variables are blue. To resolve this, I set people up to use the same theme as me for the workshop.
    • CodeSwing – Jonathan Carter, a brilliant software engineer I admire at GitHub, created this extension. This brings a Codepen-like view into your IDE. This benefits learners because they can see the visual changes they make in real-time, and its easier for them to differentiate HTML, CSS, and JavaScript code.
    • Code Tour – Jonathan Carter also developed this extension, providing guided walk-throughs in a codebase. I use this extension to keep learners on track and make remote instruction easier.
    • Code Spell Checker – This helps learners catch typos in their code!
  • After the extensions load, learners immediately see a live preview of their site and three buckets for HTML, CSS, and JavaScript via CodeSwing.
  • Next, learners receive a prompt from CodeTour asking them to update lines of code and interact with the codebase.
  • After ensuring their codebase and website is as desired, they can use the Deploy to GitHub Pages extension to publish their website.

Thats it! By utilizing Codespaces, Ive created a smooth workshop experience introducing folks to HTML, CSS, and JavaScript and deploying a website to GitHub Pages.

How to configure a Codespace for a frontend workshop

Create a Codespace

The image below exemplifies how to create a new codespace in your repository. If you have more questions about creating and configuring Codespaces beyond this blog post, check out the official GitHub documentation.

In your repository, under the green Code button, there are two tabs Local and Codespaces. Choose Codespaces and then choose create on main. This will only work if you have access to Codespaces

Add your frontend starter code

For this example, I used HTML, CSS, and JavaScript. *Please note that each file contains small errors that Im challenging workshop attendees to resolve. If you want to follow along with this blog post to learn how to set up a Codespace, you can create the following files:

index.html


<DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <title>What Time is It?</title>

  <link rel="stylesheet" href="style.css">

</head>

<body>

    <div class="clock">

      <h1 id="twelve">12</h1>

      <div class="clock-face">

        <div class="hand hour-hand"></div>

        <div class="hand min-hand"></div>

        <div class="hand second-hand"></div>

      </div>

      <!-- update the question mark to the number 6 -->

      <h1 id="six">?</h1>

    </div>

    <script src="script.js"></script>

</body>

</html>

style.css


html {

      background-size:cover;

      font-family:'helvetica neue';

      text-align: center;

      font-size: 10px;

    }

  h1{

    color: #FFC312;

    text-shadow: 2px 2px 4px #000000;

  }

    body {

      /*change the background color to a gradient of your choice*/

      background: linear-gradient(to bottom right, #47D457, #0F1CCD);

      margin: 0;

      font-size: 2rem;

      display:flex;

      flex:1;

      min-height: 100vh;

      align-items: center;

    }

    .clock {

      width: 50rem;

      height: 50rem;

      border:20px solid white;

      border-radius:50%;

      margin:50px auto;

      position: relative;

      padding:2rem;

      box-shadow:

        0 0 0 4px rgba(0,0,0,0.1),

        inset 0 0 0 3px #EFEFEF,

        inset 0 0 10px black,

        0 0 10px rgba(0,0,0,0.2);

    }

    .clock-face {

      position: relative;

      width: 100%;

      height: 100%;

      transform: translateY(-3px); /* account for the height of the clock hands */

    }

    .hand {

      width:50%;

      height:6px;

      background:lightgrey;

      position: absolute;

      top:30%;

      transform-origin: 100%;

      transform: rotate(90deg);

      transition: all 0.05s;

      transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);

      box-shadow:

        0 0 0 4px rgba(0,0,0,0.1),

        inset 0 0 0 3px #EFEFEF,

        inset 0 0 10px black,

        0 0 10px rgba(0,0,0,0.2);

    }

    #six{
      margin-top:-150px;
    }

script.js


const secondHand = document.querySelector('.second-hand');

  const minsHand = document.querySelector('.min-hand');

  const hourHand = document.querySelector('.hour-hand');

  function setDate() {

    const now = new Date();

    const seconds = now.getSeconds();

    const secondsDegrees = ((seconds / 60) * 360) + 90;

    secondHand.style.transform = `rotate(${secondsDegrees}deg)`;

    const mins = now.getMinutes();

    const minsDegrees = ((mins / 60) * 360) + ((seconds/60)*6) + 90;

    minsHand.style.transform = `rotate(${minsDegrees}deg)`;

    const hour = now.getHours();

    // change seconds to hours on the line below

    const hourDegrees = ((seconds / 12) * 360) + ((mins/60)*30) + 90;

    hourHand.style.transform = `rotate(${hourDegrees}deg)`;

  }

  setInterval(setDate, 1000);

  setDate();

Auto-load extensions

At the root of your project, create a .devcontainer folder and store a devcontainer.json file inside the folder. You can predefine specific extensions to load whenever someone opens up a Codespace by creating a devcontainer.json. Inside the devcontainer.json, you can provide the values of the VS Code extension ID. Below is an example of my devcontainer.json:

devcontainer.json


{

    "extensions": [

        "dbaeumer.vscode-eslint",

        "esbenp.prettier-vscode",

        "ms-vsliveshare.vsliveshare",

        "blackgirlbytes.deploy-to-github-pages",

        "tinkertrain.theme-panda",

        "codespaces-contrib.codeswing",

        "vsls-contrib.codetour",

        "streetsidesoftware.code-spell-checker"

    ]

}

An alternative method to add extensions to your devcontainer.json

Instead of searching for the ID of each VS Code extension, you can add them to your devcontainer.json by clicking add to devcontainer.json as pictured below:

Extension called Code Spell Checker. Click the gear icon, there is an option that says add to devcontainer.json

Set up a CodeSwing

Since CodeSwing is already installed in your IDE, you can customize the CodeSwing experience by creating a CodeSwing manifest. I used the manifest to customize my layout. I prefer the chunks of HTML, CSS, and JavaScript to stack on the right side of my editor, so I created a codeswing.json at the root of my project with the following contents:


{

    "scripts": [],

    "styles": [],

    "layout": "splitRight"

}

Not seeing any changes?

If youre not seeing any changes in your Codespace, you may need to rebuild your container or close your current Codespace and spin up a new Codespace to reload your environment.

To rebuild your environment, access your command palette and choose Codespaces: Rebuild Container. If youre not sure how to access it, check out [this guide(https://docs.github.com/en/codespaces/codespaces-reference/using-the-vs-code-command-palette-in-codespaces).

Command palette that shows a few options after typing in the words Codespaces: Re. The first option that shows is Codespaces: Rebuild Container. That's the one you want to choose

Create a code tour

Guide your workshop attendees through the workshop with a little extra help from the CodeTour extension. In my case, I left two errors in my code that I want workshop attendees to resolve:

  • I placed a question mark where the number 6 should be on the clock
  • The background colors are fine, but I prompt students to use a color palette of their choice
  • I made the hour hand goes as quickly as the minute hand

To prompt students to fix the errors, I used CodeTour to add guiding messages on specific lines in each file. At the root of my project, I created a file called main.tour. Inside my main.tour file, I added the following directions:


{

  "$schema": "https://aka.ms/codetour-schema",

  "title": "Fix The Broken Clock",

  "steps": [

    {

      "file": "index.html",

      "line": 2,

      "description": "Hey! 👋 Welcome to the Fix The Broken Clock workshop. Something is very wrong with this clock, and we need your help to fix it. Use this tour to guide you through the app, and learn how to interact with its live coding environment. Try changing their text content and watch it take effect immediately!nnClick the `Next` link below to keep learning 👇"

    },

    {

      "file": "index.html",

      "line": 22,

      "description": "Our clock has a question mark instead of the number 6. Update the `&lt;h1 id='six'>?&lt;/h1>` to render the number 6!"

    },

    {

      "file": "style.css",

      "line": 13,

      "description": "Great job at fixing the numbers over the clock. Check out background colors for the clock. Hover over the `&lt;hex>` color to choose the background color of your choice."

    },

    {

      "file": "script.js",

      "line": 14,

      "description": "The hour hand is moving just as fast as the second hand. Lets fix this by changing the word `seconds` on line 14 to `hours`."

    },

    {

      "file": "script.js",

      "line": 18,

      "description": "Mission complete! Thank you for completing this workshop."

    }

  ]

}

This code tour should look resemble the below screenshots:

First code tour prompt appears on line 2 in the index.html file. It says, "Hey! 👋 Welcome to the Fix The Broken Clock workshop. Something is very wrong with this clock, and we need your help to fix it. Use this tour to guide you through the app, and learn how to interact with its live coding environment. Try changing their text content and watch it take effect immediately!nnClick the `Next` link below to keep learning 👇"

Code tour step 2 of 5

Code tour step 3 of 5

Code tour step 4 of 5

Code tour step 5 of 5

Commit and push changes

Even the most experienced engineers struggle with version control, so Im not expecting beginner developers to write git commands during the workshop. Fortunately, Codespaces and VS Code have a source control UI. I use the UI to help attendees stage, commit, and push their changes.

Source control panel

Go live!

There are two things I recognize new developers love:

  1. The instant gratification they get as they modify a locally hosted website

  2. Showing others their first website to friends and family

I encourage workshop attendees to deploy their websites on GitHub Pages, so they can show off their first website to friends and family. It may feel more difficult for beginner developers to deploy to GitHub Pages because it requires tinkering with GitHub Actions and the GitHub UI. Instead, I have them use an extension called Deploy to GitHub Pages, which allows participants to deploy a website without leaving their IDE. This short blog post outlines how to use the extension. The live website for this demo lives here.

Deploy to GitHub Pages extension in the command palette

Make the workshop available in VS Code

If someone preferred to use VS Code over Codespaces to follow your work, you could still define the recommended extensions installed for that project. Create a .vscode folder at the root of your project with an extensions.json file inside. You can use the contents of my extensions.json file for reference.

extensions.json


{

    "recommendations": [

        "dbaeumer.vscode-eslint",

        "esbenp.prettier-vscode",

        "ms-vsliveshare.vsliveshare",

        "blackgirlbytes.deploy-to-github-pages",

        "tinkertrain.theme-panda",

        "codespaces-contrib.codeswing",

        "vsls-contrib.codetour",

        "streetsidesoftware.code-spell-checker"

    ],

}

This works with any frontend framework!

Although I used HTML, CSS, and JavaScript in my example, you can use this method for any frontend framework. I plan to create future blog posts explaining how to use Codespaces to run workshops for other technologies, but for now, I hope this is a good starting point!

Check out my sample repo

Sidenote

Dont confuse Codespaces with GitHub.dev, a lightweight in-browser editor that shows up if you press the . key in any repository. Many folks have told me they love Codespaces and showed me GitHub.dev. While I love GitHub.dev because it makes it easier for me to edit and format files quickly, its not the same as Codespaces. Codespaces is GitHub.dev on steroids.

What else do you want to learn about Codespaces? Comment below, so I can create more content to educate you on optimizing Codespace for your use case!