Install & Compatibility
Where this runs
tested against v1.0.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.910 runs
installs and imports cleanly · install 0.0s · import 0.242s · 94.8MB
glibcpy 3.10–3.910 runs
installs and imports cleanly · install 3.7s · import 0.265s · 87MB
92MB installed
● package 92MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
gdstk
✓ import gdstk
The entire library is typically imported as 'gdstk'.
gdstk.Cell
✓ cell = gdstk.Cell('my_cell')
Commonly used classes like Cell, Library, and Polygon are accessed directly as attributes of the 'gdstk' module.
This quickstart creates a simple GDSII file named 'first.gds' containing a library with a single cell named 'FIRST'. This cell contains a rectangle on layer 1 and a triangle (polygon) on layer 2. It demonstrates the basic steps of creating a library, adding a cell, adding geometric shapes, and writing the output to a GDSII file. [6, 9]
import gdstk
# Create a new library
lib = gdstk.Library()
# Create a new cell and add it to the library
cell = lib.new_cell('FIRST')
# Create a rectangle and add it to the cell
rectangle = gdstk.rectangle((0, 0), (2, 2), layer=1, datatype=0)
cell.add(rectangle)
# Create a polygon from vertices and add it to the cell
polygon_points = [(3, 0), (5, 2), (5, 0)]
polygon = gdstk.Polygon(polygon_points, layer=2)
cell.add(polygon)
# Save the library to a GDSII file
lib.write_gds('first.gds')
print("Generated first.gds with a rectangle and a polygon.")
Debug
Known issues
gotchaOlder GDSII formats have a hard limit of 199 vertices per polygon. While gdstk supports modern GDSII which often ignores this, generated files for older systems might fail to open or render incorrectly if this limit is exceeded. [6]fixWhen writing GDSII files, set the `max_points` argument in `lib.write_gds(..., max_points=199)` to ensure polygons are fractured if they exceed this limit, ensuring compatibility with older GDSII readers. Alternatively, verify target tool chain supports modern GDSII.
affects: <=1.0.0
gotchaGDSII files only support 'weakly simple' polygons (segments can intersect but not cross). Complex shapes with holes or self-intersecting boundaries are not directly supported as GDSII paths and might be stored as polygonal objects, losing path information. [6]fixBe aware that complex paths might be converted to polygons upon saving. Use `gdstk.boolean` and `gdstk.offset` operations carefully to manage complex geometries and ensure they conform to GDSII's weakly simple polygon definition.
affects: <=1.0.0
gotchaPerforming boolean operations (`gdstk.boolean`) inside a Python loop for many individual polygons can be significantly slower than expected compared to batch processing or native CAD tools. This is a common performance bottleneck. [11]fixWhere possible, collect all polygons into lists and perform boolean operations on entire lists of polygons at once. This allows `gdstk` to optimize the underlying C++ computations. For example, `gdstk.boolean(list_of_polygons_1, list_of_polygons_2, 'or')`.
affects: <=1.0.0
breakingSome users have reported issues with OASIS files losing paths or containing missing shapes after being read and then written back by gdstk, potentially leading to DRC errors in production flows. [12]fixVerify the integrity of OASIS files after read/write cycles, especially with complex or high-volume designs, by comparing with original files or performing design rule checks. Monitor GitHub issues for updates and consider upgrading to versions with specific fixes for OASIS file handling.
affects: 0.9.x, 1.0.0 (potentially resolved in future minor updates for 1.0.0)
Errors
Common errors & fixes
TypeError: 'builtin_function_or_method' object is not subscriptable
Attempting to access elements of a GDSII/OASIS library (e.g., cells) using square brackets directly on the `Library.cells` attribute, which is a list, not a dictionary. `lib.cells` returns a list of Cell objects. [5]
fixTo access cells by name, convert `lib.cells` to a dictionary or iterate through the list. Example: `cells_by_name = {c.name: c for c in lib.cells}; my_cell = cells_by_name['CELL_NAME']` or `for cell in lib.cells: if cell.name == 'CELL_NAME': my_cell = cell; break`. gdstk.gdstk.GdsError: Invalid GDSII file or corrupted stream.
The GDSII file being read is either malformed, corrupted, or not a valid GDSII format, preventing gdstk from parsing it correctly.
fixEnsure the GDSII file is valid and not corrupted. Try opening it with a different GDSII viewer (e.g., KLayout) to confirm its integrity. If generated by another tool, check that tool's output settings.
ValueError: Layer or datatype must be a non-negative integer.
Layer or datatype arguments to geometric functions (e.g., `gdstk.rectangle`, `gdstk.Polygon`) were provided with `None` or a non-integer value.
fixAlways provide non-negative integer values for `layer` and `datatype` parameters when creating GDSII elements. For example, `gdstk.rectangle((0,0), (1,1), layer=0, datatype=0)`.
Upgrade
Version history
1.0.0latest on PyPI · released Feb 21, 2026
Audit
Dependencies
zlibrequiredRequired for file compression/decompression in GDSII/OASIS files.
qhullrequiredRequired for geometric computations, specifically convex hulls and other operations.
numpyrequiredUsed for numerical operations and array handling within the Python interface.