1 week with GitHub Copilot: Building an app using only Copilot
Tags: github, nextjs, react, webdev
Published: 2021-08-16 18:29:24

**Written by [Evgeny Klimenchenko] (https://blog.logrocket.com/author/evgenyklimenchenko/)** ✏️

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 features

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.

![Adding A First Function And Comment To See How Copilot Responds](https://blog.logrocket.com/wp-content/uploads/2021/08/generating-function-and-comment.gif)

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.

![Opening Copilot's Suggestions](https://blog.logrocket.com/wp-content/uploads/2021/08/Open-suggestions.gif)

## Can you build an application with only GitHub Copilot?

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.

### Setting up the project

I chose [Next.js and React to build this project](https://blog.logrocket.com/next-js-vs-react-developer-experience/) 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.

### Developing the API endpoints

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 endpoint

To 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:

```javascript
// get random quote from random API
```

Clicking the comment, Copilot responds with a list of different options to pick from.

![Writing Command To Trigger Copilot To Get A Random Quote From An API](https://blog.logrocket.com/wp-content/uploads/2021/08/get-quote-API.gif)

The suggestion I selected was the following:

```javascript
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.

![Declaring A Function And Its Name To See If Copilot Adds Correct Implementation](https://blog.logrocket.com/wp-content/uploads/2021/08/Declaring-function-name.gif)

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 endpoint

For the `get_sentiment` function, I chose Copilot’s suggestion and didn’t have to change anything.

I input the following:

```javascript
// determine if the text is positive or negative
```

Then, Copilot suggested the following code, which I used:

```javascript
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:

```javascript
export default async function handler(req
```

And then, Copilot suggested the following, which I selected:

```javascript
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.

### React components

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:

```javascript
// 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.

```javascript
const QuoteTextBox = (props) => {
  const { quote } = props
  return (
    <div className="quote-text-box">
      <p>{quote}</p>
    </div>
  )
}

export default QuoteTextBox
```

![Copilot Suggests A Simple Function Component](https://blog.logrocket.com/wp-content/uploads/2021/08/Suggest-simple-function-component.gif)

### `SentimentTextBox`

To build the sentiment text box, I added the following comment:

```javascript
// 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:

```javascript
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.

![SentimentTextBox Suggestion From Copilot](https://blog.logrocket.com/wp-content/uploads/2021/08/SentimentTextBox-suggestion.gif)

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`.

#### Controller component with button

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:

```javascript
// 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:

```javascript
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.

![Copilot Suggests Two Hooks](https://blog.logrocket.com/wp-content/uploads/2021/08/Copilot-suggests-two-Hooks.gif)

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.

![Call And Map getSentiment Hook](https://blog.logrocket.com/wp-content/uploads/2021/08/call-map-getSentiment.gif)

And this is my final version after some minor changes from my side:

```javascript
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
```

## The final application

After experimenting with my simple quote-generating app, I found that Copilot gives enough help to create a simple application.

![Final Quote Generator App](https://blog.logrocket.com/wp-content/uploads/2021/08/Final-quote-generator-app.gif)

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.

## Copilot pros and cons

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.

### Copilot pros

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.

### Copilot cons

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.

## Conclusion

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.

---

## Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, [try LogRocket] (https://www2.logrocket.com/react-performance-monitoring).

[![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6v4gw3tgq2topvafgpgz.png)](https://www2.logrocket.com/react-performance-monitoring)[![LogRocket Dashboard Free Trial Banner] (https://blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png)](https://www2.logrocket.com/react-performance-monitoring)

[LogRocket] (https://www2.logrocket.com/react-performance-monitoring) is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — [start monitoring for free] (https://www2.logrocket.com/react-performance-monitoring).