Turtle Viewer
Run Python turtle programs directly inside VS Code. No Tkinter window, no popups — every drawing command renders live on an HTML5 canvas in a panel beside your code.
Features
Inline rendering
Every forward(), circle(), goto(), and dot() call draws on a real canvas in a VS Code webview. No external window ever opens.
Re-run & speed control
Click Re-run to instantly restart the script. Drag the Speed slider from slow step-through all the way to instant playback.
Zoom & pan
Scroll to zoom in or out. Drag the canvas to pan. Double-click to reset the view.
Interactive mode
onclick, onkey, onkeypress, mainloop, and exitonclick all work. Enable the Interactive checkbox in the toolbar to send mouse clicks and keypresses to your script in real time.
Input dialogs
turtle.textinput(), turtle.numinput(), and Python's built-in input() all pop up a VS Code input box and return the result to your script.
Console panel
print() output appears in a console panel below the canvas. Input prompts and responses are echoed there too.
Error highlighting
Runtime errors appear as an overlay on the canvas with a Go to line button that jumps your cursor to the failing line.
End button
If your script gets stuck in an infinite loop, click End to kill it cleanly — no error overlay.
Multiple turtles
t1 = turtle.Turtle(); t2 = turtle.Turtle() creates independent turtles, each with its own position, color, pen, and shape.
Quick Start
- Open any
.py file that contains import turtle or from turtle import …
- A play button appears in the editor toolbar (top-right)
- Click it — a Turtle Viewer panel opens beside your code and starts drawing
Tip: Use the Speed slider to slow down drawing and watch each step, or keep it at max for instant output.
Requirements
- VS Code 1.85 or newer
- Python 3 available on your
PATH (or configured via the Python extension)
- No Python packages needed — the shim is bundled with the extension
Supported API
| Category |
Functions |
| Movement |
forward / fd, backward / bk, left / lt, right / rt, goto / setpos, setx, sety, home |
| State |
position / pos, xcor, ycor, heading, distance, towards |
| Pen |
penup / pu, pendown / pd, pensize / width, pencolor, fillcolor, color, isdown, pen, speed |
| Shapes |
circle, dot |
| Cursor |
shape ("classic" "arrow" "turtle" "circle" "square" "triangle" "blank") |
| Fill |
begin_fill, end_fill, filling |
| Visibility |
showturtle / st, hideturtle / ht, isvisible |
| Text |
write (bold, italic, and move=True supported) |
| Screen |
setup, screensize, bgcolor, colormode, clear, reset, window_width, window_height |
| Input |
textinput, numinput, built-in input() |
| Events |
onclick / onscreenclick, onkey / onkeyrelease, onkeypress, listen, ontimer |
| Lifecycle |
mainloop / done, exitonclick, bye |
| No-ops |
tracer, delay, update, title, stamp |
| OOP |
Turtle(), Screen(), getscreen() |
Examples
Basic drawing
import turtle
turtle.speed(0)
turtle.bgcolor("black")
turtle.pencolor("cyan")
for i in range(36):
turtle.forward(200)
turtle.right(170)
turtle.hideturtle()
turtle.done()
Multiple turtles
import turtle
t1 = turtle.Turtle()
t1.color("red")
t1.shape("turtle")
t2 = turtle.Turtle()
t2.color("blue")
t2.shape("circle")
t2.penup()
t2.goto(100, 0)
t2.pendown()
for _ in range(4):
t1.forward(100)
t1.left(90)
t2.forward(100)
t2.right(90)
turtle.done()
Animation with ontimer
import turtle
screen = turtle.Screen()
t = turtle.Turtle()
t.speed(0)
angle = 0
def step():
global angle
t.setheading(angle)
t.forward(3)
angle += 7
screen.ontimer(step, 30)
screen.ontimer(step, 30)
screen.mainloop()
Interactive clicks
import turtle
screen = turtle.Screen()
screen.bgcolor("black")
def draw_dot(x, y):
t = turtle.Turtle()
t.hideturtle()
t.penup()
t.goto(x, y)
t.dot(20, "yellow")
screen.onclick(draw_dot)
# Enable "Interactive" in the toolbar, then click the canvas
screen.mainloop()
import turtle
name = input("What is your name? ")
turtle.write(f"Hello, {name}!", font=("Arial", 24, "bold"))
turtle.done()
Known Limitations
stamp() / clearstamp() are no-ops
undo() is not implemented
bgpic() (background image) is not supported
setworldcoordinates() is not supported
write(move=True) estimates text width rather than measuring it precisely
ontimer uses a select-based loop — works on macOS and Linux; on Windows it falls back to blocking (timers still fire, but between events only)