GitHub just announced Copilot, an AI-powered code completion tool that goes far beyond traditional autocomplete. Built on OpenAI’s Codex model (trained on billions of lines of public code), it suggests entire functions, writes tests, and seems to understand context in remarkable ways.
I got access to the technical preview. Here’s what I’ve learned.
What Copilot Does
Beyond Autocomplete
Traditional autocomplete suggests variable names and method signatures. Copilot suggests entire implementations:
# Traditional autocomplete:
# Type "def calculate_" → suggests "calculate_total"
# Copilot:
# Type comment "# function to calculate compound interest"
# Copilot suggests:
def calculate_compound_interest(principal, rate, time, n):
"""
Calculate compound interest.
Args:
principal: Initial amount
rate: Annual interest rate (as decimal)
time: Time period in years
n: Number of times interest compounds per year
Returns:
Final amount after compound interest
"""
return principal * (1 + rate/n) ** (n * time)
Context Awareness
Copilot reads your open file and understands patterns:
// Given this context in a file
type User struct {
ID string
Email string
Name string
CreatedAt time.Time
}
type UserRepository interface {
Create(user User) error
GetByID(id string) (User, error)
// Copilot suggests:
GetByEmail(email string) (User, error)
Update(user User) error
Delete(id string) error
List(limit, offset int) ([]User, error)
}
// Start typing implementation
func (r *PostgresUserRepository) GetByID(id string) (User, error) {
// Copilot completes with appropriate SQL and scanning
}
Test Generation
Comment your intent, get tests:
// test for user authentication
describe('UserAuthentication', () => {
// Copilot suggests entire test suites
it('should authenticate valid user', async () => {
const user = { email: 'test@example.com', password: 'password123' };
const result = await auth.authenticate(user);
expect(result.success).toBe(true);
expect(result.token).toBeDefined();
});
it('should reject invalid password', async () => {
const user = { email: 'test@example.com', password: 'wrong' };
const result = await auth.authenticate(user);
expect(result.success).toBe(false);
expect(result.error).toBe('Invalid credentials');
});
it('should reject non-existent user', async () => {
const user = { email: 'nonexistent@example.com', password: 'password' };
const result = await auth.authenticate(user);
expect(result.success).toBe(false);
});
});
Where It Excels
Boilerplate Code
Copilot eliminates tedious boilerplate:
// JSON marshaling, error handling, HTTP handlers
func (h *Handler) CreateUser(w http.ResponseWriter, r *http.Request) {
// Type the function signature, Copilot suggests the rest:
var req CreateUserRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
user, err := h.service.CreateUser(r.Context(), req)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
}
Common Algorithms
Standard algorithms appear almost instantly:
# binary search implementation
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
API Integration
If you’re using a popular API, Copilot knows patterns:
# Send message with Twilio
from twilio.rest import Client
def send_sms(to_number, message):
client = Client(
os.environ['TWILIO_ACCOUNT_SID'],
os.environ['TWILIO_AUTH_TOKEN']
)
message = client.messages.create(
body=message,
from_=os.environ['TWILIO_PHONE_NUMBER'],
to=to_number
)
return message.sid
Where It Struggles
Domain-Specific Logic
Copilot doesn’t understand your business:
# This won't work well:
# "calculate customer discount based on our loyalty program"
# Copilot might suggest generic logic, but your actual rules
# (10% for gold members, 15% for platinum, 5% for orders > $100)
# require human specification
Complex Algorithms
Novel or complex algorithms need human design:
# Copilot can implement quicksort from scratch
# But won't design your custom distributed consensus algorithm
Security-Sensitive Code
Be cautious:
# Copilot might suggest:
password = request.args.get('password') # Query param for password - bad
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}") # SQL injection
# Always review security implications
Practical Usage
Workflow Integration
copilot_workflow:
good_for:
- Starting new functions (write comment first)
- Generating boilerplate
- Writing tests for existing code
- Learning API patterns
- Converting between formats
not_good_for:
- Designing architecture
- Security review
- Understanding existing code
- Domain-specific logic
Tips for Better Suggestions
better_suggestions:
write_good_comments:
- Clear, specific descriptions
- Include input/output types
- Mention edge cases
name_things_well:
- Descriptive function names
- Clear variable names
- Copilot uses these as context
provide_context:
- Keep related code in same file
- Import statements help
- Type definitions matter
iterate:
- Tab to accept
- Ctrl+] for next suggestion
- Edit and let Copilot re-suggest
Concerns and Considerations
Code Licensing
Copilot is trained on public GitHub code:
licensing_questions:
- What about copyleft licenses (GPL)?
- Is suggested code derivative work?
- Who owns Copilot-generated code?
- GitHub's ToS vs code licenses
# Currently unclear, watch for legal developments
Code Quality
Copilot suggests patterns from training data:
quality_considerations:
good:
- Common patterns well-represented
- Popular libraries covered
- Multiple suggestion options
bad:
- May suggest outdated patterns
- Security anti-patterns in training data
- Copy-paste bugs propagated
mitigation:
- Always review suggestions
- Run tests and linters
- Treat as junior developer's code
Learning Impact
Will developers learn less?
learning_considerations:
concerns:
- Juniors may not understand suggested code
- Less practice writing from scratch
- Pattern recognition atrophies
counterpoints:
- Frees time for higher-level thinking
- Exposure to many patterns
- Still need to understand to modify
recommendation:
- Turn off occasionally
- Understand before accepting
- Use for learning patterns
The Bigger Picture
What This Signals
ai_assisted_development:
current:
- Code completion (Copilot)
- Bug detection (DeepCode)
- Code review assistance
coming:
- Natural language to code
- Automated refactoring
- Architecture suggestions
- Full feature generation
human_role:
- Architecture and design
- Requirements understanding
- Review and quality
- Domain expertise
My Take
After a week with Copilot:
assessment:
productivity_impact:
- Significant for boilerplate
- Moderate for general coding
- None for complex problems
quality_impact:
- Depends entirely on review
- Don't blindly accept
- Test everything
recommendation:
- Try it
- Use thoughtfully
- Stay critical
Key Takeaways
- Copilot is a significant step in AI-assisted development—not just autocomplete
- Excels at boilerplate, common patterns, and API integration
- Struggles with domain logic, novel algorithms, and security
- Always review suggestions; treat as junior developer code
- Licensing questions remain unresolved
- Won’t replace developers but will change how we work
- Write good comments and use descriptive names for better suggestions
- Stay critical and don’t let fundamentals atrophy
This is the beginning of a significant shift. AI won’t write all our code, but it will increasingly write the boring parts. The question is what we do with the time we save.