|
| 1 | +--- |
| 2 | +title: Using GitHub Copilot to reduce technical debt |
| 3 | +shortTitle: Reduce technical debt |
| 4 | +intro: 'Use {% data variables.product.prodname_copilot_short %} to automate refactoring and maintenance tasks, freeing your team to focus on feature development.' |
| 5 | +versions: |
| 6 | + feature: copilot |
| 7 | +topics: |
| 8 | + - Copilot |
| 9 | +contentType: tutorials |
| 10 | +category: |
| 11 | + - Burn down tech debt |
| 12 | + - Author and optimize with Copilot |
| 13 | +--- |
| 14 | + |
| 15 | +## Introduction |
| 16 | + |
| 17 | +Technical debt accumulates in every codebase: duplicate code, missing tests, outdated dependencies, and inconsistent patterns. These issues can accumulate because feature development is typically given a higher priority. This tutorial explains how you can use {% data variables.product.prodname_copilot %} to tackle technical debt systematically, without sacrificing feature velocity. |
| 18 | + |
| 19 | +### Who this tutorial is for |
| 20 | + |
| 21 | +This tutorial is designed to help engineering teams and technical leads reduce technical debt while maintaining the pace at which new features are delivered. You should have: |
| 22 | + |
| 23 | +* A {% data variables.product.prodname_copilot_short %} subscription with access to {% data variables.copilot.copilot_coding_agent %} |
| 24 | +* Admin access to at least one repository |
| 25 | +* Familiarity with your team's development workflow |
| 26 | + |
| 27 | +### What you'll accomplish |
| 28 | + |
| 29 | +By the end of this tutorial, you'll have learned about: |
| 30 | + |
| 31 | +* Using {% data variables.product.prodname_copilot_short %} to implement in-the-moment fixes |
| 32 | +* Leveraging {% data variables.copilot.copilot_coding_agent %} for large-scale cleanup tasks |
| 33 | +* Creating custom instructions to align {% data variables.product.prodname_copilot_short %} with your team's standards |
| 34 | +* Measuring the impact of {% data variables.product.prodname_copilot_short %} on your technical debt |
| 35 | + |
| 36 | +## Understanding the technical debt problem |
| 37 | + |
| 38 | +Before starting to reduce the technical debt in a codebase, you should take some time to identify the types of technical debt your team faces most often. |
| 39 | + |
| 40 | +Common types of technical debt include: |
| 41 | + |
| 42 | +* **Code duplication** - The same logic implemented in multiple places |
| 43 | +* **Missing tests** - Features without adequate test coverage |
| 44 | +* **Outdated dependencies** - Libraries several versions behind current releases |
| 45 | +* **Inconsistent patterns** - Different approaches to the same problem across your codebase |
| 46 | +* **Legacy code** - Old code that works but doesn't follow current standards |
| 47 | + |
| 48 | +The cost of technical debt compounds over time: |
| 49 | + |
| 50 | +* Senior engineers spend time on routine updates instead of architecture design |
| 51 | +* Code reviews become longer as reviewers debate inconsistent patterns |
| 52 | +* New developers take longer to onboard due to confusing code organization |
| 53 | +* Deployment risk increases as outdated dependencies accumulate vulnerabilities |
| 54 | + |
| 55 | +## Using {% data variables.product.prodname_copilot_short %} in your IDE for in-the-moment fixes |
| 56 | + |
| 57 | +The best way to avoid technical debt accumulating in your codebase is to prevent it getting into the codebase in the first place. |
| 58 | + |
| 59 | +When you encounter technical debt during development, fix it immediately using {% data variables.product.prodname_copilot_short %} in your IDE. |
| 60 | + |
| 61 | +### Quick refactoring workflow |
| 62 | + |
| 63 | +1. While working in your IDE, highlight code that needs improvement. |
| 64 | +1. Open {% data variables.copilot.copilot_chat_short %} in the IDE. |
| 65 | +1. Ask {% data variables.product.prodname_copilot_short %} to refactor the code. For example: |
| 66 | + |
| 67 | + * `Extract this into a reusable helper and add error handling` |
| 68 | + * `Standardize this logging format to match our pattern` |
| 69 | + * `Add null checks for all optional parameters` |
| 70 | + * `Replace this deprecated API call with the current version` <!-- markdownlint-disable-line GHD046 --> |
| 71 | + |
| 72 | +1. Review the suggested changes. |
| 73 | +1. Accept the changes or ask {% data variables.product.prodname_copilot_short %} to modify its approach. |
| 74 | +1. Run your tests to verify the changes work correctly. |
| 75 | + |
| 76 | +### Example: Standardizing error handling |
| 77 | + |
| 78 | +If you find inconsistent error handling—for example: |
| 79 | + |
| 80 | +```javascript id="err-handling" |
| 81 | +// Highlight this code |
| 82 | +try { |
| 83 | + await fetchData(); |
| 84 | +} catch (e) { |
| 85 | + console.log(e); |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +Ask {% data variables.product.prodname_copilot_short %} to improve the code—for example: |
| 90 | + |
| 91 | +```copilot prompt copy ref="err-handling" |
| 92 | +Refactor this to use structured logging and proper error handling |
| 93 | +``` |
| 94 | + |
| 95 | +{% data variables.product.prodname_copilot_short %} might suggest: |
| 96 | + |
| 97 | +```javascript |
| 98 | +try { |
| 99 | + await fetchData(); |
| 100 | +} catch (error) { |
| 101 | + logger.error('Failed to fetch data', { |
| 102 | + error: error.message, |
| 103 | + stack: error.stack, |
| 104 | + timestamp: new Date().toISOString() |
| 105 | + }); |
| 106 | + throw error; |
| 107 | +} |
| 108 | +``` |
| 109 | + |
| 110 | +> [!NOTE] This response is an example. {% data variables.copilot.copilot_chat_short %} responses are non-deterministic, so you may get a different response if you run the same prompt against the same code. |
| 111 | +
|
| 112 | +By adopting the in-the-moment fix approach, you help to ensure that substandard code does not get added to your codebase, and you avoid the creation of a backlog issue that may never be addressed. |
| 113 | + |
| 114 | +For more details on using {% data variables.product.prodname_copilot_short %} in your IDE, see [AUTOTITLE](/copilot/using-github-copilot/asking-github-copilot-questions-in-your-ide). |
| 115 | + |
| 116 | +## Using {% data variables.copilot.copilot_coding_agent %} for large-scale refactoring |
| 117 | + |
| 118 | +Some refactoring tasks are just too big to complete while everyone on the team is busy developing new features. In this situation you can use {% data variables.copilot.copilot_coding_agent %} to handle these tasks autonomously. Human effort will still be required—at a minimum for reviewing the changes {% data variables.copilot.copilot_coding_agent %} proposes—but getting {% data variables.product.prodname_copilot_short %} to do the bulk of the work can allow you to carry out large-scale refactoring with much less impact on your team's productivity. |
| 119 | + |
| 120 | +### When to use {% data variables.copilot.copilot_coding_agent %} |
| 121 | + |
| 122 | +Use {% data variables.copilot.copilot_coding_agent %} for tasks that: |
| 123 | + |
| 124 | +* Touch many files across your codebase |
| 125 | +* Require systematic changes (like removing old feature flags) |
| 126 | +* Need careful testing but are straightforward to implement |
| 127 | +* Would interrupt feature development if done manually |
| 128 | + |
| 129 | +Examples include: |
| 130 | + |
| 131 | +* Framework upgrades that affect 50+ files |
| 132 | +* Removing deprecated feature flags <!-- markdownlint-disable-line GHD046 --> |
| 133 | +* Migrating to strict TypeScript |
| 134 | +* Updating dependency versions |
| 135 | +* Standardizing import patterns |
| 136 | + |
| 137 | +### Workflow for {% data variables.copilot.copilot_coding_agent %} |
| 138 | + |
| 139 | +1. Create a {% data variables.product.prodname_dotcom %} issue describing the refactoring task. |
| 140 | + |
| 141 | + Be specific about what needs to change. For example: |
| 142 | + |
| 143 | + ```markdown |
| 144 | + Remove all feature flags marked for cleanup in Q2. |
| 145 | + |
| 146 | + These flags are: |
| 147 | + - `enable_new_dashboard` |
| 148 | + - `beta_export_feature` |
| 149 | + - `experimental_search` |
| 150 | + |
| 151 | + All three flags are enabled by default in production. |
| 152 | + |
| 153 | + Remove the flag checks and keep the "enabled" code path. |
| 154 | + ``` |
| 155 | + |
| 156 | +1. Assign the issue to the **Copilot** user. |
| 157 | +1. {% data variables.copilot.copilot_coding_agent %} will: |
| 158 | + |
| 159 | + * Set up a development environment |
| 160 | + * Open a draft pull request |
| 161 | + * Make the required changes to the code |
| 162 | + * Run your tests |
| 163 | + * Finalize the pull request for review |
| 164 | + * Request your review of the pull request |
| 165 | + |
| 166 | +1. Review the pull request just as you would a pull request raised by a human. |
| 167 | +1. Leave comments if changes are needed—{% data variables.copilot.copilot_coding_agent %} will update the pull request based on your feedback. |
| 168 | +1. Iterate in this way until the work is completed correctly. |
| 169 | +1. Approve and merge the pull request. |
| 170 | + |
| 171 | +For more information, see [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr#assigning-an-issue-to-copilot) and [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/review-copilot-prs). |
| 172 | + |
| 173 | +### Safety guardrails |
| 174 | + |
| 175 | +{% data variables.copilot.copilot_coding_agent %} operates with built-in safety measures: |
| 176 | + |
| 177 | +* It can only push to its own `copilot/*` branches |
| 178 | +* It cannot merge pull requests—requires your approval |
| 179 | +* All commits are logged and auditable |
| 180 | +* Your existing branch protections remain active |
| 181 | +* CI/CD checks run before any code is merged |
| 182 | + |
| 183 | +## Creating custom instructions for your team |
| 184 | + |
| 185 | +Custom instructions help {% data variables.product.prodname_copilot_short %} understand your team's coding standards and patterns. This ensures suggestions match your expectations from the start. |
| 186 | + |
| 187 | +### Setting up custom instructions |
| 188 | + |
| 189 | +1. In your repository, create a file named `.github/copilot-instructions.md`. |
| 190 | +1. Add your team's coding standards in clear, straightforward statements—for example, using bulleted lists. |
| 191 | +1. Commit the file to your repository. |
| 192 | + |
| 193 | +### Example custom instructions |
| 194 | + |
| 195 | +Here's an example of effective custom instructions: |
| 196 | + |
| 197 | +```markdown |
| 198 | +## Our Standards |
| 199 | + |
| 200 | +- Use structured logging, not console.log |
| 201 | +- Sanitize user input before database queries |
| 202 | +- Check for null/undefined on all optional parameters |
| 203 | +- Keep functions under 50 lines (extract helpers if needed) |
| 204 | +- Every public function needs a test |
| 205 | +- Flag any loops that might trigger N+1 queries |
| 206 | + |
| 207 | +## Error Handling |
| 208 | + |
| 209 | +- Always use try-catch blocks for async operations |
| 210 | +- Log errors with context (user ID, request ID, timestamp) |
| 211 | +- Never swallow errors silently |
| 212 | +- Return appropriate HTTP status codes |
| 213 | + |
| 214 | +## Testing Requirements |
| 215 | + |
| 216 | +- Unit tests for all business logic |
| 217 | +- Integration tests for API endpoints |
| 218 | +- Mock external services in tests |
| 219 | +- Test both success and failure paths |
| 220 | +``` |
| 221 | + |
| 222 | +For detailed guidance on writing custom instructions, see [AUTOTITLE](/copilot/customizing-copilot/adding-custom-instructions-for-github-copilot). |
| 223 | + |
| 224 | +### Benefits of custom instructions |
| 225 | + |
| 226 | +With custom instructions in place: |
| 227 | + |
| 228 | +* {% data variables.product.prodname_copilot_short %} suggests code following your patterns |
| 229 | +* Code reviews become faster, with fewer discussions about style changes |
| 230 | +* New team members learn your standards through {% data variables.product.prodname_copilot_short %} suggestions |
| 231 | +* Consistency improves across your codebase |
| 232 | + |
| 233 | +## Running a pilot program |
| 234 | + |
| 235 | +Start small to validate {% data variables.product.prodname_copilot_short %}'s impact on your technical debt before rolling it out widely. |
| 236 | + |
| 237 | +### Week 1: Set up and establish baselines |
| 238 | + |
| 239 | +1. Ensure all pilot participants have {% data variables.product.prodname_copilot_short %} access with {% data variables.copilot.copilot_coding_agent %} enabled. |
| 240 | +1. Count the technical debt items in your backlog: |
| 241 | + |
| 242 | + * Number of "tech debt", "chore", or similar labeled issues |
| 243 | + * Number of outdated dependencies |
| 244 | + * Number of files failing linter checks |
| 245 | + |
| 246 | +1. Track current metrics: |
| 247 | + |
| 248 | + * Average time from pull request creation to merge for refactoring PRs |
| 249 | + * Average number of review rounds per refactoring PR |
| 250 | + |
| 251 | +1. Create your first `.github/copilot-instructions.md` file with 3–5 of your most important standards. |
| 252 | + |
| 253 | +### Weeks 2–4: Run the pilot |
| 254 | + |
| 255 | +1. Select 5–10 repositories for your pilot. |
| 256 | +1. Choose 1–2 specific problems to address. For example: |
| 257 | + |
| 258 | + * Code duplication in a particular area |
| 259 | + * Missing tests on frequently changed files |
| 260 | + * Outdated dependencies |
| 261 | + |
| 262 | +1. Use {% data variables.product.prodname_copilot_short %} in your IDE for quick fixes as you encounter issues. |
| 263 | +1. Assign larger cleanup tasks to {% data variables.copilot.copilot_coding_agent %}. |
| 264 | +1. Review all {% data variables.product.prodname_copilot_short %}-generated PRs carefully. |
| 265 | +1. Provide feedback on suggestions to help {% data variables.product.prodname_copilot_short %} learn your preferences. |
| 266 | + |
| 267 | +### Week 5: Evaluate results |
| 268 | + |
| 269 | +After the pilot, measure your results: |
| 270 | + |
| 271 | +* How much faster are refactoring pull requests getting merged? |
| 272 | +* How many review rounds do they require now? |
| 273 | +* Which types of code change suggestions, made by {% data variables.copilot.copilot_coding_agent %} in pull requests, did developers accept most often? |
| 274 | +* Which suggestions needed the most revision? |
| 275 | +* Are your technical debt metrics improving? |
| 276 | + |
| 277 | + * Linter warnings decreasing? |
| 278 | + * Test coverage increasing? |
| 279 | + * Dependency versions more current? |
| 280 | + |
| 281 | +Update your custom instructions based on what you learned about which guidance helped {% data variables.product.prodname_copilot_short %} most. |
| 282 | + |
| 283 | +## Measuring success |
| 284 | + |
| 285 | +Track specific metrics to understand {% data variables.product.prodname_copilot_short %}'s impact on your technical debt. |
| 286 | + |
| 287 | +### Velocity metrics |
| 288 | + |
| 289 | +Monitor how {% data variables.product.prodname_copilot_short %} affects development speed: |
| 290 | + |
| 291 | +* Time to close technical debt issues (target: 30–50% reduction) |
| 292 | +* Number of technical debt pull requests merged per week (target: 2–3x increase) |
| 293 | +* Average number of review cycles per refactoring pull request (assess whether this increased or decreased) |
| 294 | + |
| 295 | +### Quality metrics |
| 296 | + |
| 297 | +Ensure quality improves alongside velocity: |
| 298 | + |
| 299 | +* Linter warning count (this should trend downward) |
| 300 | +* Test coverage percentage (this should trend upward) |
| 301 | +* Number of production incidents related to refactored code (assess whether this changed) |
| 302 | + |
| 303 | +### Engineer satisfaction |
| 304 | + |
| 305 | +Survey your team regularly: |
| 306 | + |
| 307 | +* Are engineers spending less time on routine maintenance? |
| 308 | +* Are code reviews focusing more on architecture and less on style? |
| 309 | +* Is onboarding faster for new team members? |
| 310 | + |
| 311 | +## Troubleshooting |
| 312 | + |
| 313 | +### {% data variables.product.prodname_copilot_short %} suggests incorrect changes |
| 314 | + |
| 315 | +If {% data variables.product.prodname_copilot_short %} consistently suggests code that doesn't match your needs: |
| 316 | + |
| 317 | +* Review your custom instructions—they may be too vague or contradictory |
| 318 | +* Provide more specific context in your prompts |
| 319 | +* Add examples of good code to your custom instructions |
| 320 | +* Leave detailed feedback in pull request reviews to allow {% data variables.copilot.copilot_coding_agent %} to fix the problems |
| 321 | + |
| 322 | +### Pull requests are too large to review |
| 323 | + |
| 324 | +If {% data variables.copilot.copilot_coding_agent %} creates pull requests that are difficult to review: |
| 325 | + |
| 326 | +* Break large tasks into smaller, focused issues |
| 327 | +* Ask {% data variables.copilot.copilot_coding_agent %} to handle one file or directory at a time |
| 328 | +* Use more specific issue descriptions |
| 329 | + |
| 330 | +### Changes break tests |
| 331 | + |
| 332 | +If refactoring introduces test failures: |
| 333 | + |
| 334 | +* Ensure your test suite runs reliably before using {% data variables.copilot.copilot_coding_agent %} |
| 335 | +* Review {% data variables.product.prodname_copilot_short %} changes carefully before merging |
| 336 | +* Ask {% data variables.product.prodname_copilot_short %} to update tests along with the code changes |
| 337 | + |
| 338 | +### Team adoption is slow |
| 339 | + |
| 340 | +If your team isn't using {% data variables.product.prodname_copilot_short %} for technical debt: |
| 341 | + |
| 342 | +* Share success stories from early adopters |
| 343 | +* Demonstrate time savings in team meetings |
| 344 | +* Start with the most annoying technical debt items |
| 345 | +* Make creating custom instructions a team activity |
| 346 | + |
| 347 | +## Conclusion |
| 348 | + |
| 349 | +In this tutorial, you learned how to use {% data variables.product.prodname_copilot_short %} to systematically reduce technical debt. You now know how to: |
| 350 | + |
| 351 | +* Fix technical debt immediately using {% data variables.product.prodname_copilot_short %} in your IDE |
| 352 | +* Assign large refactoring tasks to {% data variables.copilot.copilot_coding_agent %} |
| 353 | +* Create custom instructions that align {% data variables.product.prodname_copilot_short %} with your team's standards |
| 354 | +* Run a pilot program to validate the approach |
| 355 | +* Measure {% data variables.product.prodname_copilot_short %}'s impact on technical debt |
| 356 | + |
| 357 | +By automating routine refactoring and maintenance tasks, {% data variables.product.prodname_copilot_short %} frees you to focus on architecture, feature development, and other high-value work. |
| 358 | + |
| 359 | +### Quick survey |
| 360 | + |
| 361 | +{% note %} |
| 362 | + |
| 363 | +After reading this tutorial, do you feel confident you can use {% data variables.product.prodname_copilot_short %} to reduce the technical debt in a codebase? |
| 364 | + |
| 365 | +<a href="https://docs.github.io/success-test/yes.html" target="_blank" class="btn btn-outline mt-3 mr-3 no-underline"><span>Yes</span></a> <a href="https://docs.github.io/success-test/no.html" target="_blank" class="btn btn-outline mt-3 mr-3 no-underline"><span>No</span></a> |
| 366 | + |
| 367 | +{% endnote %} |
| 368 | + |
| 369 | +## Next steps |
| 370 | + |
| 371 | +* **Expand your pilot**: Roll out to more repositories based on your pilot results. |
| 372 | +* **Automate dependency updates**: Create recurring issues for {% data variables.copilot.copilot_coding_agent %} to handle dependency updates. |
| 373 | +* **Build a refactoring queue**: Label issues in your backlog as good for {% data variables.product.prodname_copilot_short %} then regularly assign a batch of these to {% data variables.product.prodname_copilot_short %} to work on. |
| 374 | +* **Share best practices**: Document successful prompts and custom instructions for your team. |
| 375 | + |
| 376 | +## Further reading |
| 377 | + |
| 378 | +* [AUTOTITLE](/copilot/using-github-copilot/coding-agent) |
| 379 | +* [AUTOTITLE](/copilot/tutorials/refactoring-code-with-github-copilot) |
| 380 | +* [How to use GitHub Copilot in your IDE: Tips, tricks, and best practices](https://github.blog/developer-skills/github/how-to-use-github-copilot-in-your-ide-tips-tricks-and-best-practices/) in the {% data variables.product.company_short %} blog |
| 381 | +* [5 ways to integrate GitHub Copilot coding agent into your workflow](https://github.blog/ai-and-ml/github-copilot/5-ways-to-integrate-github-copilot-coding-agent-into-your-workflow/) in the {% data variables.product.company_short %} blog |
0 commit comments