How to run a frontend workshop in Codespaces
Use Codespaces to teach HTML, CSS, and JavaScript to beginner developers

Developer Advocate @ GitHub
Search for a command to run...
Use Codespaces to teach HTML, CSS, and JavaScript to beginner developers

Developer Advocate @ GitHub
Thanks for putting this together. I (and some friends) have been discussing teaching classes to kids on different programming topics as a way to give back. This article not only inspired me to further action, but now I can use codespaces as a platform for it.
In this series, I will document technical tutorials for navigating GitHub's awesome features!
GitHub Pages now uses customizable GitHub Action workflows to build and deploy your code so that developers can control their authoring framework and deployment. GitHub Pages is a powerful option for storing static content for the following reasons: ...
Raise your hand if you've been personally victimized by the question: 'Will AI replace software engineers?' It's a common debate that drives developers to extremes—either avoiding AI entirely or frantically signing up for every AI course available. ...
I recently went down several rabbit holes about building WYSIWYG editors and popovers. While on maternity leave, I finally have time to deeply explore random technical problems without deadlines - a rare opportunity. Thus far, I've focused on contrib...
This blog post uses storytelling to introduce beginners to Verifiable Credentials, followed by a tutorial on creating them in JavaScript and Kotlin. In Our Last Issue... In our previous issue, we met Dawson Webhart, a junior frontend software enginee...

"Our current credit system says, 'Saddle yourself, so we can give you more to saddle.'" Eric Lapin, President of FormFree, stated during a recent TBD live stream. His comment sheds light on a fundamental paradox of the U.S. credit system: it often re...

Technology adoption doesn't happen with one software engineer coding in solitude. Even though big companies like Meta and Microsoft boast of their humble beginnings in a dorm room or a garage, product adoption requires good marketing. Many software e...

Black Girl Bytes
58 posts
I'm a Developer Advocate at GitHub. I'm passionate about community, code, and education! Reach out to me on Twitter ❤️
Since 2018, I’ve 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 don’t 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 it’s 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.
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 I created for each participant resembles the following:
That’s it! By utilizing Codespaces, I’ve created a smooth workshop experience introducing folks to HTML, CSS, and JavaScript and deploying a website to GitHub Pages.
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.

For this example, I used HTML, CSS, and JavaScript. *Please note that each file contains small errors that I’m 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:
<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>
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;
}
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();
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:
{
"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"
]
}
devcontainer.jsonInstead 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:

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"
}
If you’re 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 you’re 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).

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:
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!\n\nClick 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 `<h1 id='six'>?</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 `<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. Let’s 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:





Even the most experienced engineers struggle with version control, so I’m 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.

There are two things I recognize new developers love:
The instant gratification they get as they modify a locally hosted website
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.

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.
{
"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"
],
}
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!
Don’t 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, it’s 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!