Claude-skill-registry clojure-malli
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/clojure-malli" ~/.claude/skills/majiayu000-claude-skill-registry-clojure-malli && rm -rf "$T"
manifest:
skills/data/clojure-malli/SKILL.mdsource content
Malli Data Validation
Malli validates data against schemas. Schemas are Clojure data structures.
Quick Validation
(require '[malli.core :as m]) (require '[malli.error :as me]) ;; Validate (m/validate [:map [:name :string] [:age :int]] {:name "Alice" :age 30}) ;; => true ;; Get errors (-> [:map [:name :string] [:age :int]] (m/explain {:name "Alice" :age "thirty"}) (me/humanize)) ;; => {:age ["should be an integer"]}
Quick Coercion
(require '[malli.transform :as mt]) ;; Decode string input to proper types (m/decode [:map [:port :int] [:active :boolean]] {:port "8080" :active "true"} (mt/string-transformer)) ;; => {:port 8080, :active true} ;; Coerce = decode + validate (throws on error) (m/coerce [:map [:id :int]] {:id "42"} (mt/string-transformer)) ;; => {:id 42}
Common Schema Patterns
Maps with Required/Optional Keys
[:map [:id :uuid] ;; required [:name :string] ;; required [:email {:optional true} :string] ;; optional [:role {:default "user"} :string]] ;; optional with default
Constrained Values
[:string {:min 1 :max 100}] ;; string length 1-100 [:int {:min 0 :max 150}] ;; integer range [:enum "draft" "published"] ;; one of these values [:re #".+@.+\..+"] ;; regex match
Collections
[:vector :int] ;; vector of ints [:set :keyword] ;; set of keywords [:map-of :keyword :string] ;; map with keyword keys, string values [:tuple :double :double] ;; fixed [x, y] pair
Unions and Conditionals
;; Simple union [:or :string :int] ;; Nilable [:maybe :string] ;; string or nil ;; Tagged union with dispatch [:multi {:dispatch :type} [:user [:map [:type [:= :user]] [:name :string]]] [:admin [:map [:type [:= :admin]] [:role :string]]]]
Nested Structures
[:map [:user [:map [:name :string] [:address [:map [:city :string] [:zip :string]]]]]]
Performance: Cache Validators
;; BAD - creates validator every call (defn process [data] (when (m/validate schema data) ...)) ;; GOOD - cached validator (def valid? (m/validator schema)) (defn process [data] (when (valid? data) ...)) ;; Same for decoders (def decode-request (m/decoder schema (mt/string-transformer))) (def coerce-request (m/coercer schema (mt/string-transformer)))
Key Gotchas
- decode doesn't validate - returns invalid data as-is. Use
for safety.coerce - Maps are open by default - extra keys allowed. Use
to reject them.{:closed true} - Keys are required by default - use
for optional keys.{:optional true}
Detailed References
- Schema Syntax - All builtin types, properties, operators
- API Reference - Core functions with signatures
- Registries - Reusable schema patterns