diff --git a/packages/p/poulpy1337/ui_lib/base.gno b/packages/p/poulpy1337/ui_lib/base.gno
new file mode 100644
index 0000000..5742b89
--- /dev/null
+++ b/packages/p/poulpy1337/ui_lib/base.gno
@@ -0,0 +1,28 @@
+package svg
+
+import (
+ "strings"
+)
+
+type SvgElementer interface {
+ render() string
+}
+
+type SvgElement struct {
+ color string
+ class string
+ x int
+ y int
+ width int
+ height int
+ children []SvgElementer
+}
+
+func (e *SvgElement) renderChildren() string {
+ var childrenStr strings.Builder
+ for _, child := range e.children {
+ childrenStr.WriteString("\n ")
+ childrenStr.WriteString(child.render())
+ }
+ return childrenStr.String()
+}
diff --git a/packages/p/poulpy1337/ui_lib/canvas.gno b/packages/p/poulpy1337/ui_lib/canvas.gno
new file mode 100644
index 0000000..688ac05
--- /dev/null
+++ b/packages/p/poulpy1337/ui_lib/canvas.gno
@@ -0,0 +1,33 @@
+package svg
+
+import (
+ "strconv"
+)
+
+type SvgCanvas struct {
+ SvgElement
+ viewBox string
+ style string
+}
+
+func NewSvgCanvas(width, height int, viewBox string, style string, children ...SvgElementer) *SvgCanvas {
+ return &SvgCanvas{
+ SvgElement: SvgElement{
+ width: width,
+ height: height,
+ children: children,
+ class: "",
+ },
+ viewBox: viewBox,
+ style: style,
+ }
+}
+
+func (s *SvgCanvas) Render() string {
+ children := s.renderChildren()
+ return ``
+}
diff --git a/packages/p/poulpy1337/ui_lib/circle.gno b/packages/p/poulpy1337/ui_lib/circle.gno
new file mode 100644
index 0000000..ffcc456
--- /dev/null
+++ b/packages/p/poulpy1337/ui_lib/circle.gno
@@ -0,0 +1,41 @@
+package svg
+
+import (
+ "strconv"
+)
+
+type SvgCircle struct {
+ SvgElement
+ radius int
+}
+
+func NewSvgCircle(x, y, radius int, color string, class string, children ...SvgElementer) *SvgCircle {
+ return &SvgCircle{
+ SvgElement: SvgElement{
+ color: color,
+ class: class,
+ x: x,
+ y: y,
+ children: children,
+ },
+ radius: radius,
+ }
+}
+
+func (c *SvgCircle) render() string {
+ children := c.renderChildren()
+ if children == "" {
+ return ``
+ }
+ return `
+ ` + children + `
+`
+}
diff --git a/packages/p/poulpy1337/ui_lib/gnomod.toml b/packages/p/poulpy1337/ui_lib/gnomod.toml
new file mode 100644
index 0000000..c8bdfc8
--- /dev/null
+++ b/packages/p/poulpy1337/ui_lib/gnomod.toml
@@ -0,0 +1,2 @@
+module = "gno.land/p/poulpy1337/ui_lib"
+gno = "0.9"
diff --git a/packages/p/poulpy1337/ui_lib/group.gno b/packages/p/poulpy1337/ui_lib/group.gno
new file mode 100644
index 0000000..14ec731
--- /dev/null
+++ b/packages/p/poulpy1337/ui_lib/group.gno
@@ -0,0 +1,25 @@
+package svg
+
+type SvgGroup struct {
+ SvgElement
+ id string
+}
+
+func NewSvgGroup(id string, children ...SvgElementer) *SvgGroup {
+ return &SvgGroup{
+ SvgElement: SvgElement{
+ children: children,
+ },
+ id: id,
+ }
+}
+
+func (g *SvgGroup) render() string {
+ children := g.renderChildren()
+ if g.id != "" {
+ return `` + children + `
+`
+ }
+ return `` + children + `
+`
+}
diff --git a/packages/p/poulpy1337/ui_lib/rect.gno b/packages/p/poulpy1337/ui_lib/rect.gno
new file mode 100644
index 0000000..9ca3d03
--- /dev/null
+++ b/packages/p/poulpy1337/ui_lib/rect.gno
@@ -0,0 +1,47 @@
+package svg
+
+import (
+ "strconv"
+)
+
+type SvgRect struct {
+ SvgElement
+ roundness int
+}
+
+func NewSvgRect(x, y, width, height int, roundness int, color string, class string, children ...SvgElementer) *SvgRect {
+ return &SvgRect{
+ SvgElement: SvgElement{
+ color: color,
+ class: class,
+ x: x,
+ y: y,
+ width: width,
+ height: height,
+ children: children,
+ },
+ roundness: roundness,
+ }
+}
+
+func (r *SvgRect) render() string {
+ children := r.renderChildren()
+ if children == "" {
+ return ``
+ }
+ return `
+ ` + children + `
+`
+}
diff --git a/packages/p/poulpy1337/ui_lib/text.gno b/packages/p/poulpy1337/ui_lib/text.gno
new file mode 100644
index 0000000..b447acf
--- /dev/null
+++ b/packages/p/poulpy1337/ui_lib/text.gno
@@ -0,0 +1,41 @@
+package svg
+
+import (
+ "strconv"
+)
+
+type SvgText struct {
+ SvgElement
+ text string
+}
+
+func NewSvgText(x, y int, text string, color string, class string, children ...SvgElementer) *SvgText {
+ return &SvgText{
+ SvgElement: SvgElement{
+ color: color,
+ class: class,
+ x: x,
+ y: y,
+ width: 0,
+ height: 0,
+ children: children,
+ },
+ text: text,
+ }
+}
+
+func (r *SvgText) render() string {
+ children := r.renderChildren()
+ if children == "" {
+ return `` + r.text + ""
+ }
+ return `
+ ` + r.text + "" + children + `
+`
+}