GitHub Copilot is the newest tool developed by GitHub to autocomplete code with the help of OpenAI.
Copilot generates smart code suggestions with context, such as docstrings, code comments, function names, or even file names. It then uses all this information to suggest code snippets that developers can easily accept by pressing the Tab key on a keyboard.
It understands Python, JavaScript, TypeScript, Ruby, and Go, as well as dozens of other languages because it’s “trained on billions of lines of public code,” per the Copilot website. And while it’s currently still in its limited technical preview, those interested can sign up to join a waitlist to try it out.
In this article, we’ll explore Copilot’s main functionalities, how to build a simple application using only Copilot, and its pros and cons.
Copilot’s main feature is its autocomplete function. When typing a function description, for example, Copilot completes the whole function before a user finishes. While this autocomplete is similar to other general autocomplete functionalities, Copilot goes a step beyond.
When continuing to write code and adding more comments, Copilot begins to understand the whole context of the code through its AI capabilities. With the context, it autocompletes comments mid-sentence.
For example, by adding a function, it generates a whole comment and a function; in this case, it figured out the last function should be a multiply function, as seen below.
Another cool feature of Copilot is the ability to see 10 full-page suggestions, instead of a single one-liner suggestion, and choosing which suits the code best.
To do that, press ^ + Return
on a Mac keyboard or Ctrl + Enter
on Windows to open a list of suggestions, as shown below.
With Copilot’s capabilities, I wanted to challenge myself to build a small application using only Copilot. For this challenge, I wanted to create a simple random quote application that also displays the sentiment of the quote.
To do this, I had a few rules to follow to see how much benefit I could receive from Copilot.
First, I could not search the internet if I encountered a problem, including using Stack Overflow or documentation. This let me see whether it was possible to solely rely on Copilot’s suggestions to create working code.
The second rule was that I could not write any new code myself. I could, however, write comments, variables, names, and function names to trigger Copilot’s suggestions. Similarly, I could also make small edits to the suggested code.
And finally, I could trigger the list of Copilot suggestions and accept one, since this is a built-in feature.
I chose Next.js and React to build this project since they are the tools I am most familiar with to help me better evaluate Copilot’s performance.
Since React makes it fairly painless for developers to build applications, and I wanted to see how Copilot would manage React components.
For Next.js, it provides a good starting point where I didn’t need to spend a lot of time setting everything up, and it has built-in back-end functions, making it useful to call different API endpoints without triggering CORS errors.
While Next.js might seem too powerful for this small project, there’s no need to install other dependencies beforehand and its integrated, easy-to-use API functions make it a good choice for this challenge.
Starting with developing API endpoints, I wanted a quote generator that returns a random quote on a GET
request and a sentiment analysis endpoint. The sentiment analysis endpoint needed to receive a string as a query parameter and return a sentiment.
Since I didn’t know what format the return value would be, I let Copilot write it and see what it could return.
/api/get_quote
GET
request endpointTo create two endpoints using Next.js, I created two files in the api
folder: get_quote.js
and get_sentiment.js
. Next.js could then create these endpoints based on the file names. All that was left is to define was the handler functions inside those files, and I let Copilot do that for me.
For the get_quote
endpoint, I wrote a comment and chose a good suggestion:
// get random quote from random API
Clicking the comment, Copilot responds with a list of different options to pick from.
The suggestion I selected was the following:
const getQuote = async () => { const response = await fetch('https://quotes.rest/qod.json') const quote = await response.json() return quote.contents.quotes[0].quote }
This suggestion worked. Almost all of the other suggestions that I checked were either broken or required an API key that I didn’t have. This could be because Copilot was trained on open source GitHub code, and some endpoints might be outdated already, which can be frustrating.
Also, this endpoint returns the quote of the day, which means for every call, I receive the same quote for the current day, which was not what I was expecting. Instead, for every endpoint call, I wanted to receive a different random quote.
For the second part of this endpoint, I needed to create a handler for the endpoint that calls the function Copilot already generated. The handler is the function that Next.js calls when the client requests the endpoint.
To do this, I declared the function with its name to see whether Copilot would suggest the correct implementation or not.
And Copilot surprised me again. Everything seemed correct.
First, it called the getQuote
function and returned the quote received from the web service. Then, it saved the quote to the constant and returned JSON to the client with the retrieved quote. The only thing I had to add was .status(200)
to send the 200
status code to the client.
/api/get_sentiment
GET
request endpointFor the get_sentiment
function, I chose Copilot’s suggestion and didn’t have to change anything.
I input the following:
// determine if the text is positive or negative
Then, Copilot suggested the following code, which I used:
async function getSentiment(text) { const response = await fetch(`http://text-processing.com/api/sentiment/`, { method: "POST", body: `text=${text}`, headers: { "Content-Type": "application/x-www-form-urlencoded", }, }) const json = await response.json() return json.label }
However, for the endpoint part, I had to add .status(200)
, similar to the get_quote
endpoint.
Here is what I provided to Copilot:
export default async function handler(req
And then, Copilot suggested the following, which I selected:
export default async function handler(req, res) { const sentiment = await getSentiment(req.query.text) res.json({ sentiment }) }
Copilot managed to provide us with a working solution again, suggesting the right handler and calculating what the get_sentiment
handle function needed to return. This suggestion looks similar to the one we had previously.
Let’s see how Copilot handled React component generation next.
For the frontend, I needed a couple of specified React components and a React controller component with a button. The two specified components needed to display text: one for quote text and another for sentiment text.
Let’s see how Copilot handled creating these React components.
QuoteTextBox
I began with the QuoteTextBox
component that would showcase a simple quote; I added the following comment to see what Copilot would suggest:
// React component to show a quote inside a div const
Copilot suggested a simple function component, which I did not have to change at all.
const QuoteTextBox = (props) => { const { quote } = props return ( <div className="quote-text-box"> <p>{quote}</p> </div> ) } export default QuoteTextBox
SentimentTextBox
To build the sentiment text box, I added the following comment:
// React component to show sentiment text inside a div const
For this text box, it was a bit trickier to find the right suggestions, and I had to scroll through most of them until I found one that would work with my code:
const SentimentTextBox = (props) => { // Get sentiment text from props const sentimentText = props.sentimentText // Return component return ( <div className="sentiment-text-box"> {sentimentText} </div> ) } // Export component export default SentimentTextBox
It’s important to clearly understand what to expect from Copilot because it is only a tool, and developers can’t just rely on the first suggestion it gives.
I still needed to come back to this component to map what the API returns to readable text. For example, if the web service returns neg
, I needed to map it to Negative
.
I also needed a controller component to manage all the logic. The first two React components I created just received data and rendered it on-screen, but the controller component needed to manage the API calls.
I started by inputting the following:
// React component that uses QuiteTextBox and SentimentTextBox and APIs to show quotes and sentiment with a button to generate new quotes. const
Then, Copilot brought this suggestion:
const QuoteGenerator = ({quote, sentiment, onClick}) => { return ( <div> <QuoteTextBox quote={quote} sentiment={sentiment} /> <button onClick={onClick}>Generate New Quote</button> <SentimentTextBox sentiment={sentiment} /> </div> ) } export default QuoteGenerator
The controller component suggested by Copilot appeared to be pretty basic; it lacked the API calls and didn’t use correct props for SentimentTextBox
. However, Copilot did provide the correct structure, it just needed some tweaks to finish it.
Then, I just needed to add functions to the controller component. Instead of passing quote
, sentiment
, and onClick
, I asked Copilot to generate them. I also needed some Hooks to store the sentiment and quote data received from calling the APIs.
For Hooks, Copilot figured out right away what I needed. To trigger the suggestion for the first Hook, I began typing a comment and Copilot suggested the correct Hook.
However, for the second Hook, I didn’t even need to type a comment. I accepted the first Hook suggestion, moved to the next line, and Copilot suggested the second Hook immediately.
While the endpoints were correct, I still needed to make some changes to make them work. I had to ask very specifically what I wanted, otherwise, Copilot started suggesting different web services.
I wanted it to just call endpoints that were already created. Furthermore, I need to specifically call the getSentiment
endpoint when I received a quote and map the sentiment to human-readable text.
And this is my final version after some minor changes from my side:
const QuoteGenerator = () => { // Hook to store text in state const [quoteText, setQuoteText] = React.useState('') const [sentimentText, setSentimentText] = React.useState('') // Function to get quotes from API /api/get-quote const getQuote = () => { fetch('/api/get-quote') .then(response => response.json()) .then(json => { setQuoteText(json.quote) getSentiment(json.quote) }) } // Function to get sentiment from API /api/get-sentiment\ const getSentiment = (text) => { fetch('/api/get-sentiment?text=' + text) .then(response => response.json()) .then(json => { setSentimentText(json.sentiment) }) } // Function to be called when user clicks on button to generate new quote const onClick = () => { getQuote() } const mapSentimentToText = { 'neg': 'Negative', 'pos': 'Positive', 'neutral': 'Neutral' } return ( <div> <QuoteTextBox quote={quoteText} /> <SentimentTextBox sentimentText={mapSentimentToText[sentimentText]} /> <button onClick={onClick}>Generate New Quote</button> </div> ) } export default QuoteGenerator
After experimenting with my simple quote-generating app, I found that Copilot gives enough help to create a simple application.
I didn’t have high expectations and initially thought I would need to change a lot of code to make the application work.
However, Copilot surprised me. In some places, it gave me nonsense suggestions, but in other places, the suggestions were so good that I can’t believe Copilot made them.
To recap my experience with Copilot, I’ve compiled the pros and cons of working with it so you can decide whether Copilot is something you can use daily or not.
The main advantage of using Copilot is that it provides autocomplete on steroids. As an autocomplete tool, I believe it is currently the best on the market; there is nothing even close to as useful as Copilot.
Copilot also shows developers multiple ways to solve different problems that may not be so obvious. When in need of a code snippet, the 10 suggestions functionality is great and can often be used in place of Stack Overflow for efficiency.
In all, Copilot is fun to use. For all the tech geeks, it is something new to play around with and it makes daily work a bit more interesting.
While its functionality provides greater efficiency, users must remember it’s a tool, not a human developer replacement. Because Copilot is not a panacea, users cannot solely rely on it for all their code. Most of its suggestions require changes to fit specific needs.
And finally, I noticed Copilot was suggesting to use React classes for small components with little logic instead of functional components with Hooks. Because it was trained on openly available code on GitHub, Copilot might provide some depreciated suggestions for coding.
GitHub Copilot is not something that can just listen to a project idea and code everything for you. It is also not taking over developer jobs, either. But it is something that can make coding easier.
GitHub Copilot is good with small tasks; when you start asking it something more complex, you often get nonsense. Nevertheless, it is a very good tool for both beginner and experienced developers alike.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.
Handle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.
2 Replies to "1 week with GitHub Copilot: Building an app using only Copilot"
Very insightful article, Thanks
Well a lot of programming languages have had IDs that have done most of this for years. Without AI. Also the comments generated well those are the kind you probably should never ride anyways. Most, should be why and then I say I won’t be able to do that. Maybe it’ll get better and be useful.