Join patterns provide a higher level concurrent programming construct than the explicit use of threads and locks and have typically been implemented with special syntax and run-time support. This paper presents a strikingly simple design for a small number of higher order combinators which can be composed together to realize a powerful set of join patterns as a library in an existing language. The higher order combinators enjoy a lock free implementation that uses software transactional memory (STM). This allows joins patterns to be implemented simply as a library and provides a transformational semantics for join patterns.