{"id":14982980,"url":"https://github.com/jreijn/spring-comparing-template-engines","last_synced_at":"2025-04-04T21:10:07.778Z","repository":{"id":11688291,"uuid":"14199740","full_name":"jreijn/spring-comparing-template-engines","owner":"jreijn","description":"Demo project to show different Java templating engines in combination with Spring MVC","archived":false,"fork":false,"pushed_at":"2023-12-15T15:09:28.000Z","size":232,"stargazers_count":424,"open_issues_count":8,"forks_count":117,"subscribers_count":23,"default_branch":"master","last_synced_at":"2025-03-28T20:09:11.037Z","etag":null,"topics":["java","spring-mvc","template-engine"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"github/gitignore","license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jreijn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-11-07T09:39:01.000Z","updated_at":"2025-02-24T09:09:10.000Z","dependencies_parsed_at":"2023-02-19T05:55:14.838Z","dependency_job_id":"e2314ed7-fa2c-437f-b10e-843f2aceae1c","html_url":"https://github.com/jreijn/spring-comparing-template-engines","commit_stats":{"total_commits":108,"total_committers":11,"mean_commits":9.818181818181818,"dds":0.6296296296296297,"last_synced_commit":"ad015634228cfba4aad0c37c068befb5c9b2c501"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jreijn%2Fspring-comparing-template-engines","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jreijn%2Fspring-comparing-template-engines/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jreijn%2Fspring-comparing-template-engines/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jreijn%2Fspring-comparing-template-engines/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jreijn","download_url":"https://codeload.github.com/jreijn/spring-comparing-template-engines/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247249532,"owners_count":20908212,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","spring-mvc","template-engine"],"created_at":"2024-09-24T14:06:31.850Z","updated_at":"2025-04-04T21:10:07.755Z","avatar_url":"https://github.com/jreijn.png","language":"Java","funding_links":[],"categories":["\u003ca name=\"Java\"\u003e\u003c/a\u003eJava"],"sub_categories":[],"readme":"# Comparing Template engines for Spring MVC\n\n[![Build Status](https://travis-ci.org/jreijn/spring-comparing-template-engines.png?branch=master)](https://travis-ci.org/jreijn/spring-comparing-template-engines)\n\nThis is a demo project, which accompanied my [\"Shoot-out! Template engines for the JVM\"](http://www.slideshare.net/jreijn/comparing-templateenginesjvm) presentation, which shows the differences among several Java template engines in combination with Spring MVC. Template engines used in this project are:\n\n* JSP + [JSTL](https://jstl.java.net/) - v1.2\n* [Freemarker](http://www.freemarker.org/) - v2.3.28.RELEASE\n* [Velocity](http://velocity.apache.org/) - v2.3\n* [Velocity Tools](http://velocity.apache.org/tools/) - v3.1\n* [Thymeleaf](http://www.thymeleaf.org/) - v3.0.11.RELEASE\n* Mustache - Based on [JMustache](https://github.com/samskivert/jmustache) - v1.15\n* [Scalate](http://scalate.fusesource.org/)  - v1.9.8\n* [Jade4j](https://github.com/neuland/jade4j) - v1.3.1\n* [HTTL](http://httl.github.io/en/) - v1.0.11\n* [Pebble](https://pebbletemplates.io/) - v3.1.6\n* [Handlebars](http://jknack.github.io/handlebars.java/) - v4.3.1\n* [chunk](http://www.x5software.com/chunk/) - v3.6.2\n* [HtmlFlow](https://github.com/xmlet/HtmlFlow/) - v4.0\n* [Trimou](http://trimou.org/) - v2.5.1.Final\n* [Rocker](https://github.com/fizzed/rocker/) - v1.3.0\n* [Ickenham](https://github.com/enpassant/ickenham) - v1.5.0\n* [Rythm](http://rythmengine.org/) - v1.4.1\n* [Groovy Templates](https://groovy.apache.org/) - v2.5.6\n* [Liqp - Jekyll](https://github.com/bkiers/Liqp) - v0.8.5.3\n* [kolinx.html](https://github.com/Kotlin/kotlinx.html) - v1.8.22\n\n## Build and run\nYou need Java 8 and Maven 3 to build and run this project.\nBuild the project with\n\n    mvn package\n\nRun the project with\n\n    mvn spring-boot:run\n\nSee the demo URLs:\n\n  - http://localhost:8080/jsp or http://localhost:8080/\n  - http://localhost:8080/freemarker\n  - http://localhost:8080/velocity\n  - http://localhost:8080/thymeleaf\n  - http://localhost:8080/jade\n  - http://localhost:8080/scalate\n  - http://localhost:8080/mustache\n  - http://localhost:8080/pebble\n  - http://localhost:8080/handlebars\n  - http://localhost:8080/httl  \n  - http://localhost:8080/chunk\n  - http://localhost:8080/htmlFlow\n  - http://localhost:8080/trimou\n  - http://localhost:8080/rocker\n  - http://localhost:8080/ickenham\n  - http://localhost:8080/rythm\n  - http://localhost:8080/groovy\n  - http://localhost:8080/liqp\n  - http://localhost:8080/kotlinx\n\n## Benchmarking\n\nIn case you want to benchmark the different template engines I would recommend using Apache HTTP server benchmarking tool or Siege an HTTP/HTTPS stress tester.\nYou can try any of the following URLs.\n\n    $ ab -n 10000 -c 10 http://localhost:8080/jsp\n    $ ab -n 10000 -c 10 http://localhost:8080/velocity\n    $ ab -n 10000 -c 10 http://localhost:8080/freemarker\n    $ ab -n 10000 -c 10 http://localhost:8080/thymeleaf\n    $ ab -n 10000 -c 10 http://localhost:8080/mustache\n    $ ab -n 10000 -c 10 http://localhost:8080/jade\n    $ ab -n 10000 -c 10 http://localhost:8080/pebble\n    $ ab -n 10000 -c 10 http://localhost:8080/handlebars\n    $ ab -n 10000 -c 10 http://localhost:8080/scalate\n    $ ab -n 10000 -c 10 http://localhost:8080/httl\n    $ ab -n 10000 -c 10 http://localhost:8080/chunk\n    $ ab -n 10000 -c 10 http://localhost:8080/htmlFlow\n    $ ab -n 10000 -c 10 http://localhost:8080/trimou\n    $ ab -n 10000 -c 10 http://localhost:8080/rocker\n    $ ab -n 10000 -c 10 http://localhost:8080/ickenham\n    $ ab -n 10000 -c 10 http://localhost:8080/rythm\n    $ ab -n 10000 -c 10 http://localhost:8080/groovy\n    $ ab -n 10000 -c 10 http://localhost:8080/liqp\n    $ ab -n 10000 -c 10 http://localhost:8080/kotlinx\n\nFor creating the below benchmark results I used ApacheBench (version 2.4.25) with the following settings:\n\n```\nab -n 25000 -c 25 -k http://localhost:8080/jsp\n```\nWith 25 concurrent requests and 25.000 requests in total this resulted in the following numbers:\n\n\n## Benchmarks 2018\n\nThese tests were done on a local machine with the following specs:\n\n```\nSpring-Boot: 2.1.2.RELEASE\nWindows 10 (1803, build: 17134.523)\n3,60 GHz Intel Core i5-8350U Quad core\njava version \"1.8.0_192\"\nJava(TM) SE Runtime Environment (build 1.8.0_192-b12)\nJava HotSpot(TM) 64-Bit Server VM (build 25.192-b12, mixed mode)\nApache Tomcat 9.0.14\n```\n\nResults in order (high to low):\n\nTotal time taken for processing 25.000 requests with a concurrency level of 25 (lower is better).\n\n```\nJade4j                  567.7   seconds\nHandlebars              147.7   seconds\nScalate - Scaml          33.33  seconds\nPebble                   27.92  seconds\nHTTL                     24.61  seconds\nThymeleaf                24.09  seconds\nVelocity                 23.07  seconds\nFreemarker               11.80  seconds\njTwig                    10.95  seconds\nMustache (JMustache)      8.836 seconds\nJSP                       7.888 seconds\n```\n\n## Benchmarks 10.2019\n\nThese tests were done on a local machine with the following specs:\n\n```\nSpring-Boot: 2.1.4.RELEASE\nWindows 10 (1803, build: 17134.706)\n3,60 GHz Intel Core i5-8350U Quad core\njava version \"1.8.0_221\"\nJava(TM) SE Runtime Environment (build 1.8.0_221-b11)\nJava HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)\nApache Tomcat 9.0.17\n```\n\nResults in order (high to low):\n\nTotal time taken for processing 25.000 requests with a concurrency level of 25. (lower is better)\n\n```\nGroovy                  ~ 800    seconds\nJade4j                    684.7  seconds\nHandlebars                161.8  seconds\nScalate - Scaml            34.38 seconds\nVelocity                   27.49 seconds\nPebble                     25.63 seconds\nHTTL                       22.86 seconds\njTwig                      21.23 seconds\nLiqp                       19.60 seconds\nIckenham                   19.50 seconds\nThymeleaf                  18.33 seconds\nRythm                      17.84 seconds\nRocker                     17.63 seconds\nMustache (JMustache)       15.75 seconds\nHtmlFlow                   15.62 seconds\nChunk                      15.04 seconds\nTrimou                     15.02 seconds\nFreemarker                 14.74 seconds\nJSP                        11.22 seconds\n```\n\n*Keep in mind that in the real world, these results will differ depending on the complexity of the templates, hardware, etc, so it's just an indication and if you want to know the truth you will have to run the benchmark yourself to see how such a template engine performs in your specific environment.*\n\nChunk produces pages with variable length. I haven't investigated it yet. ab might fail, and for Chunk use:\n\n    $ ab -n 25000 -c 25 -l http://localhost:8080/chunk\n\n### How were the results measured?\n\nBefore the performance of each template engines was measured, there were at least 2 dry runs with the exact same settings, to make sure that initialization of the engines, warm up of the JVM and additional caches have taken place. There were at least 5 iterations of the same benchmark before calculating the average time it took.\n\n### For Mac OS X users\n\nMac OS X has only 16K ports available that won't be released until socket\nTIME_WAIT is passed. The default timeout for TIME_WAIT is 15 seconds.\nConsider reducing in case of available port bottleneck.\n\nYou can check whether this is a problem with netstat:\n\n    # sysctl net.inet.tcp.msl\n    net.inet.tcp.msl: 15000\n\nNow if you want to change this you can do so by doing:\n\n    # sudo sysctl -w net.inet.tcp.msl=1000\n    net.inet.tcp.msl: 15000 -\u003e 1000\n\nIn case you still run into problem you might want to read [this thread](http://stackoverflow.com/questions/1216267/ab-program-freezes-after-lots-of-requests-why/1217100#1217100) on ephemeral ports.\n\n## Contributing\n\nIn case you see an improvement to the benchmark or know about ways to improve the results, please file an issue and send a pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjreijn%2Fspring-comparing-template-engines","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjreijn%2Fspring-comparing-template-engines","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjreijn%2Fspring-comparing-template-engines/lists"}