Drawer¶
projects.drawer
A classic drawer with a bottom; outside sizes.
The front has half-blind dovetails, so the tails don't show from the
front; its bottom half pins are narrow, so that the groove runs through
the bottom tails and is hidden. The back is through dovetailed. The bottom slides in grooves in
the sides and the front, under the back, which is narrower and sits on
it. The bottom's edges are rabbeted on its underside to fit the grooves,
its top flush with their tops; its grain runs from side to side, so it
moves towards the back. The groove's lower wall is groove_height above
the bottom edges. The back and the right side are mirror images of the
front and the left side, all with their reference faces outside.
Parameters¶
| Parameter | Default |
|---|---|
width |
400 |
depth |
450 |
height |
150 |
groove_height |
10 |
groove_width |
6 |
groove_depth |
5 |
stock |
20 mm board, oak |
side_stock |
12 mm board, oak |
bottom_stock |
10 mm board, oak |
Change them in a design file (see Change an example):
Drawings¶
The plans in one PDF: plans.pdf.
Cut list¶
front 400 x 150 x 20 mm oak
- 2 x sockets for 3 half-blind dovetails, 15 deep, lap 5
- groove 6 mm, 5 deep, in bottom_face
back 400 x 134 x 12 mm oak, mirror image
- 2 x sockets for 2 dovetails
left_right 445 x 150 x 12 mm oak, 2 pieces: left; mirror image: right
- 3 half-blind dovetails, 15 long, slope 1:7
- 2 dovetails, slope 1:7
- groove 6 mm, 5 deep, in bottom_face
bottom 386 x 435 x 10 mm oak
- end rabbet 5 mm, 4 deep, in bottom_face at left_end
- end rabbet 5 mm, 4 deep, in bottom_face at right_end
- rabbet 5 mm, 4 deep, in bottom_face at front_edge
Code¶
From woodwright/examples/projects.py, which imports the names it uses (see From an example to your own design):
def drawer(
width: float = 400,
depth: float = 450,
height: float = 150,
groove_height: float = 10,
groove_width: float = 6,
groove_depth: float = 5,
stock: Stock = OAK,
side_stock: Stock = SIDE_OAK,
bottom_stock: Stock = THIN_OAK,
) -> Assembly:
"""A classic drawer with a bottom; outside sizes.
The front has half-blind dovetails, so the tails don't show from the
front; its bottom half pins are narrow, so that the groove runs through
the bottom tails and is hidden. The back is through dovetailed. The bottom slides in grooves in
the sides and the front, under the back, which is narrower and sits on
it. The bottom's edges are rabbeted on its underside to fit the grooves,
its top flush with their tops; its grain runs from side to side, so it
moves towards the back. The groove's lower wall is `groove_height` above
the bottom edges. The back and the right side are mirror images of the
front and the left side, all with their reference faces outside.
"""
s, b = side_stock.thickness, bottom_stock.thickness
side_length = depth - stock.thickness - s
asm = Assembly("drawer", root_location=BOX_FRONT)
front = asm.add(Board("front", stock, length=width - 2 * s, width=height))
back_height = height - groove_height - groove_width
back = asm.add(Board("back", side_stock, length=width - 2 * s, width=back_height, mirror=True))
left = asm.add(Board("left", side_stock, length=side_length, width=height))
right = asm.add(Board("right", side_stock, length=side_length, width=height, mirror=True))
bottom = asm.add(Board("bottom", bottom_stock, length=width - 2 * s, width=side_length + s))
def in_groove(tongue: SideRef, groove: SideRef, position: Position) -> TongueAndGroove:
"""The bottom's edge or end in a groove in the inside face of the front or a side."""
return TongueAndGroove(
tongue=tongue,
groove=groove,
tongue_thickness=groove_width,
tongue_length=groove_depth,
tongue_offset=0,
position=position,
flush=(groove.part.ref_edge, bottom.bottom_face),
across=offset(groove_height + groove_width - b),
)
# The groove runs out of the front's ends: it must pass through the bottom
# tail, not through the half pin below it, which shows on the side. The
# half pin is narrowest at the lap and widens by the slope towards the
# inside (by 1:7); the groove stays at least 2 mm above it.
socket_depth = stock.thickness - rules.dovetail_lap(stock.thickness)
half_pin = math.floor(groove_height - socket_depth / 7 - 2)
# The sides' right ends are at the front; the back's top edge is flush with theirs.
for side, front_end, back_end, bottom_end in [
(left, front.left_end, back.left_end, bottom.left_end),
(right, front.right_end, back.right_end, bottom.right_end),
]:
asm.join(
HalfBlindDovetail(
tails=side.right_end, pins=front_end, tail_count=3, half_pin_width=half_pin
)
)
asm.join(
ThroughDovetail(
tails=side.left_end,
pins=back_end,
tail_count=2,
flush=(back.back_edge, side.back_edge),
)
)
asm.join(in_groove(bottom_end, side.bottom_face, flush_with(side.right_end)))
asm.join(in_groove(bottom.front_edge, front.bottom_face, flush_with(front.left_end)))
# The back sits on the bottom, which reaches to its outside face.
asm.join(Butt(bottom.top_face, back.ref_edge, flush=(bottom.back_edge, back.ref_face)))
return asm
Exported with woodwright 0.9.0 on 2026-10-25.