Skip to content

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.

Drawer, assembled

Drawer, exploded

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

from woodwright.examples import projects

design = projects.drawer(width=500)

Drawings

The plans in one PDF: plans.pdf.

Assembly

assembly

Parts

parts

Back

back

Bottom

bottom

Front

front

Left right

left right

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.