<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Xalen Technologies</title>
    <description>The latest articles on DEV Community by Xalen Technologies (@xalen).</description>
    <link>https://dev.to/xalen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3966074%2F17077978-b29e-41f8-b20a-1590b2006f9c.png</url>
      <title>DEV Community: Xalen Technologies</title>
      <link>https://dev.to/xalen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xalen"/>
    <language>en</language>
    <item>
      <title>Compute astrology charts in the browser: no node-gyp, no .se1 files, no AGPL</title>
      <dc:creator>Xalen Technologies</dc:creator>
      <pubDate>Thu, 25 Jun 2026 06:59:03 +0000</pubDate>
      <link>https://dev.to/xalen/compute-astrology-charts-in-the-browser-no-node-gyp-no-se1-files-no-agpl-5c90</link>
      <guid>https://dev.to/xalen/compute-astrology-charts-in-the-browser-no-node-gyp-no-se1-files-no-agpl-5c90</guid>
      <description>&lt;p&gt;If you've wired Swiss Ephemeris into a Node astrology app, you know the ritual. You &lt;code&gt;npm install sweph&lt;/code&gt;, and now every machine needs Python plus a C/C++ toolchain, because the package compiles Swiss's C code via node-gyp at install time (make/gcc on Linux, Xcode on macOS, Visual C++ Build Tools on Windows).&lt;/p&gt;

&lt;p&gt;It works on your laptop. Then it explodes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apple Silicon:&lt;/strong&gt; node-gyp can't find full Xcode behind Command Line Tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slim Docker / CI images:&lt;/strong&gt; no Python, no &lt;code&gt;build-essential&lt;/code&gt;, so the install dies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serverless:&lt;/strong&gt; the &lt;code&gt;.node&lt;/code&gt; binary you built locally won't load on Amazon Linux (wrong arch or glibc).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then there's the data. Neither &lt;code&gt;sweph&lt;/code&gt; nor &lt;code&gt;swisseph&lt;/code&gt; bundles the &lt;code&gt;.se1&lt;/code&gt; ephemeris files; you download them yourself and point the library at a path. The modern set is 2 MB, the full GitHub set is 100 MB. And since &lt;code&gt;2.10.1&lt;/code&gt;, &lt;code&gt;sweph&lt;/code&gt; is AGPL-3.0 (LGPL only under a professional license), a real obligation to weigh for a closed-source SaaS backend.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pure-Rust alternative
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/vedika-io/xalen-ephemeris" rel="noopener noreferrer"&gt;XALEN Ephemeris&lt;/a&gt; is an analytical engine written entirely in Rust and licensed Apache-2.0. Three things make it interesting for JS/TS devs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No node-gyp.&lt;/strong&gt; The Node addon is napi-rs, which ships prebuilt per-platform binaries via npm. No Python, no C compiler, no compile step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A real WASM build&lt;/strong&gt; via wasm-bindgen, so you compute charts client-side in the browser: no server round-trip, no backend copyleft.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero data files.&lt;/strong&gt; The core math (VSOP87A, ELP2000-82, IAU precession/nutation, an 8,870-star catalog) is analytical and compiled into the binary. No &lt;code&gt;.se1&lt;/code&gt; to host.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;xalen&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xalen-ephemeris&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// WASM build, runs in the browser&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// load the .wasm module&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xalen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;computeChart&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1990-04-12T08:30:00Z&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;28.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;77.2&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// planet longitudes, house cusps, etc.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Swiss via Node&lt;/th&gt;
&lt;th&gt;XALEN (pure Rust)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Build deps&lt;/td&gt;
&lt;td&gt;node-gyp + Python + C compiler&lt;/td&gt;
&lt;td&gt;none: prebuilt binary / &lt;code&gt;.wasm&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime data&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.se1&lt;/code&gt; files (2 to 100 MB)&lt;/td&gt;
&lt;td&gt;none, compiled in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser / WASM&lt;/td&gt;
&lt;td&gt;possible via Emscripten&lt;/td&gt;
&lt;td&gt;native wasm-bindgen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;License&lt;/td&gt;
&lt;td&gt;AGPL-3.0 / professional&lt;/td&gt;
&lt;td&gt;Apache-2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To be fair, Swiss &lt;em&gt;can&lt;/em&gt; be compiled to WASM (Emscripten ports exist, and its built-in Moshier mode is file-free). So the honest edge isn't capability, it's delivery: pure Rust straight to WASM, with no Emscripten/MEMFS shim and no data files to bundle.&lt;/p&gt;

&lt;p&gt;Honest caveat: XALEN is young and not on npm or PyPI yet (crates.io currently serves an older &lt;code&gt;0.3.1&lt;/code&gt; line). Today this is a watch-and-prototype story, not a drop-it-into-prod one.&lt;/p&gt;

&lt;p&gt;Repo: &lt;strong&gt;&lt;a href="https://github.com/vedika-io/xalen-ephemeris" rel="noopener noreferrer"&gt;github.com/vedika-io/xalen-ephemeris&lt;/a&gt;&lt;/strong&gt;. Would you ship ephemeris math to the client, or is server-side non-negotiable for you?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Swiss Ephemeris Returns 6 Floats. Your App Needs a Chart.</title>
      <dc:creator>Xalen Technologies</dc:creator>
      <pubDate>Mon, 22 Jun 2026 17:46:49 +0000</pubDate>
      <link>https://dev.to/xalen/swiss-ephemeris-returns-6-floats-your-app-needs-a-chart-4ho1</link>
      <guid>https://dev.to/xalen/swiss-ephemeris-returns-6-floats-your-app-needs-a-chart-4ho1</guid>
      <description>&lt;p&gt;Every astrology backend on earth runs on Swiss Ephemeris. It is accurate to the arcsecond and has earned three decades of trust. Now look at what it hands back.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;swisseph&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;swe&lt;/span&gt;
&lt;span class="n"&gt;xx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;swe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calc_ut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;swe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MOON&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;swe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FLG_SIDEREAL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;moon_lon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="c1"&gt;# (281.43, -4.21, 0.0026, 13.17, 0.58, -0.00003)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Six floats. Position and speed. That is the entire API for a body, and it is where Swiss stops and your real work begins.&lt;/p&gt;

&lt;h2&gt;
  
  
  Swiss computes positions, not astrology
&lt;/h2&gt;

&lt;p&gt;There is no nakshatra function. No dasha engine. No panchang, no divisional charts, no shadbala, no KP, no yogas. pyswisseph inherits the same surface,because it is a binding, not a new library. So every team rebuilds the same thousands of lines on top of &lt;code&gt;xx[0]&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# YOU write the nakshatra, the pada, the rashi,
# the Vimshottari dasha balance, the tithi/yoga/karana,
# the shadbala, the D-9, the D-10... none ships with Swiss.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you hand-roll it all into JSON, because Swiss returns C &lt;code&gt;double[6]&lt;/code&gt; arrays.&lt;/p&gt;

&lt;p&gt;What "returns a chart" looks like&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/vedika-io/xalen-ephemeris" rel="noopener noreferrer"&gt;XALEN Ephemeris&lt;/a&gt; is a pure-Rust,Apache-2.0 ephemeris that treats the interpretive layer as part of the library.&lt;br&gt;
The same Moon longitude is the input to functions that already exist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;nak&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Nakshatra&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_longitude_deg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;moon_sid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;rashi&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Rashi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_longitude_deg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;moon_sid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;panchang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;compute_panchang&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sun_sid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;moon_sid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jd&lt;/span&gt;&lt;span class="nf"&gt;.as_f64&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;dashas&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;vimshottari_dasha&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;moon_sid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jd&lt;/span&gt;&lt;span class="nf"&gt;.as_f64&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;              &lt;span class="nn"&gt;DashaLevel&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Antardasha&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the real API from &lt;code&gt;examples/vedic_chart.rs&lt;/code&gt;. And &lt;strong&gt;every public type derives &lt;code&gt;serde&lt;/code&gt;&lt;/strong&gt;, so the JSON problem vanishes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;panchang&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;It&lt;/span&gt; &lt;span class="n"&gt;even&lt;/span&gt; &lt;span class="n"&gt;renders&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;literal&lt;/span&gt; &lt;span class="n"&gt;chart&lt;/span&gt;&lt;span class="py"&gt;. Swiss&lt;/span&gt; &lt;span class="n"&gt;hands&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;six&lt;/span&gt; &lt;span class="n"&gt;floats&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;XALEN&lt;/span&gt; &lt;span class="n"&gt;hands&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;SVG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
rust&lt;br&gt;
let svg = render_north_indian(&amp;amp;chart);&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

On top of that: 50 ayanamsa systems, 23 house systems, Western aspects and
dignities, plus BaZi, Saju, Mayan, and I-Ching. None of it present in Swiss.

## And the math holds up

Positions are measured against **JPL Horizons DE440**, the same reference Swiss reads, reproducible from the test suite (`cargo test --workspace`, 2,199 passing):

- Sun: **0.21 arcsec**
- Mercury through Saturn: **under 0.76 arcsec**, zero data files (VSOP87A compiled in)
- Moon: RMS ~2.8 arcsec analytically, sub-arcsecond with the optional DE440 kernel

So you keep JPL-class positions and get the layer Swiss made you build yourself.

## The point

The question was never "is Swiss accurate." It is. The question is how much of your codebase exists only because Swiss stopped at a `double[6]` and left the chart to you. There is now a library that already wrote that part.

&amp;gt; Availability note: XALEN's crates.io, PyPI, and npm packages are not all
&amp;gt; published yet. Today you build from source; the claims above are reproducible
&amp;gt; from the repo right now. Star it to catch the release.

**github.com/vedika-io/xalen-ephemeris**

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>opensource</category>
      <category>showdev</category>
      <category>rust</category>
      <category>python</category>
    </item>
    <item>
      <title>You're One Audit Away From Open-Sourcing Your Astrology App</title>
      <dc:creator>Xalen Technologies</dc:creator>
      <pubDate>Mon, 08 Jun 2026 09:10:13 +0000</pubDate>
      <link>https://dev.to/xalen/youre-one-audit-away-from-open-sourcing-your-astrology-app-ed2</link>
      <guid>https://dev.to/xalen/youre-one-audit-away-from-open-sourcing-your-astrology-app-ed2</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48a2eori67gca4oge9p6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48a2eori67gca4oge9p6.png" alt=" " width="800" height="420"&gt;&lt;/a&gt; "Almost every horoscope app on earth links Swiss Ephemeris. Alm&lt;br&gt;
ost none of them have read its license. Here's the clause that can force you&lt;br&gt;
 to open-source your entire backend, and the pure-Rust, Apache-2.0 way out."&lt;br&gt;
tags: opensource, legal, rust, startups&lt;/p&gt;

&lt;h1&gt;
  
  
  Your Astrology SaaS Is an AGPL Time Bomb
&lt;/h1&gt;

&lt;p&gt;Here's how your astrology app was probably born.&lt;/p&gt;

&lt;p&gt;It needed planetary positions. A search for "ephemeris library" led, like every&lt;br&gt;
road does, to &lt;strong&gt;Swiss Ephemeris&lt;/strong&gt;, the C library from Astrodienst that astro.com&lt;br&gt;
itself runs on. So &lt;code&gt;pip install pyswisseph&lt;/code&gt;, a call to &lt;code&gt;swe.calc_ut()&lt;/code&gt;, the Moon comes back in the right place, and it ships.&lt;/p&gt;

&lt;p&gt;Nobody opened the license.&lt;/p&gt;

&lt;p&gt;So let's open it, because the clause sitting inside it can legally obligate you to publish the &lt;strong&gt;complete source code of your entire backend&lt;/strong&gt;  to every user who hits your API. And a closed-source product running on &lt;code&gt;pyswisseph&lt;/code&gt; right now is&lt;br&gt;
&lt;em&gt;already&lt;/em&gt; in violation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two-line version
&lt;/h2&gt;

&lt;p&gt;Swiss Ephemeris is &lt;strong&gt;dual-licensed&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AGPL-3.0&lt;/strong&gt;, free, but copyleft with a network clause, or&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A paid commercial license&lt;/strong&gt; from Astrodienst.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There is no third door. Without the commercial license, you took the AGPL.Using the software accepted its terms. Most people building on Swiss don't know they made that choice, but they made it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The clause that eats your business: AGPL Section 13
&lt;/h2&gt;

&lt;p&gt;The regular GPL has a famous loophole for SaaS: copyleft triggers on&lt;br&gt;
&lt;em&gt;distribution&lt;/em&gt;, and running software on your own server for users to access over a network is &lt;strong&gt;not&lt;/strong&gt; distribution. That's how Google runs GPL code internally without publishing anything. It's sometimes called the "ASP loophole."&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;A&lt;/strong&gt; in AGPL exists for the sole purpose of slamming that loophole shut.&lt;br&gt;
Here's the actual operative language from Section 13:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"...if you modify the Program, your modified version must prominently offer&lt;br&gt;
all users interacting with it remotely through a computer network ... an&lt;br&gt;
opportunity to receive the Corresponding Source of your version..."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Read that again with your product in mind. "&lt;strong&gt;All users interacting with it remotely through a computer network&lt;/strong&gt;" is a precise description of &lt;em&gt;every web astrology app ever built.&lt;/em&gt; Users hit your endpoint. Your endpoint computes a chart using Swiss Ephemeris. Section 13 says those users are entitled to your &lt;strong&gt;Corresponding Source&lt;/strong&gt;, and "Corresponding Source" is defined broadly enough to reach the code wrapped around the library.&lt;/p&gt;

&lt;p&gt;This is not a theoretical edge case. It is the &lt;strong&gt;designed, intended behavior&lt;/strong&gt; of the license. The AGPL is working &lt;em&gt;exactly as specified&lt;/em&gt; when it does this to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  "But it's just being called, not modified"
&lt;/h2&gt;

&lt;p&gt;This is the rationalization everyone reaches for, so let's kill it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pyswisseph is not a separate thing.&lt;/strong&gt; It's a thin C-extension wrapper that links &lt;code&gt;libswe&lt;/code&gt; directly. It inherits Swiss Ephemeris's license wholesale: the pyswisseph project says so itself. &lt;code&gt;import swisseph&lt;/code&gt; is &lt;code&gt;import AGPL&lt;/code&gt;. There is no Python-shaped escape hatch.&lt;br&gt;
And the "it wasn't modified" defense is thinner than it feels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The FSF's own position is that linking creates a combined work. Whether  your service is a "modified version" or a "work based on the Program" under the AGPL is exactly the kind of question you do &lt;em&gt;not&lt;/em&gt; want a lawyer answering for the first time during due diligence on your acquisition.&lt;/li&gt;
&lt;li&gt;Even on the most charitable reading, the whole company is now riding on a copyleft-boundary argument. That's not a foundation. That's a fault line.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The honest summary Astrodienst themselves push you toward: &lt;strong&gt;a service that isn't open-sourced needs the commercial license.&lt;/strong&gt; That's the whole reason the commercial license &lt;em&gt;exists.&lt;/em&gt; They are not selling it for fun. They are selling it to the exact people reading this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the bomb actually goes off
&lt;/h2&gt;

&lt;p&gt;AGPL violations rarely blow up on day one. They blow up at the worst possible moment, because that's when someone finally reads the dependency manifest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fundraising / acquisition due diligence.&lt;/strong&gt; The acquirer's legal team runs a license scan. &lt;code&gt;AGPL-3.0&lt;/code&gt; lights up red next to your core IP. The deal stalls while you scramble to either rip out the dependency or back-pay a commercial license. This exact scenario has tanked timelines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An enterprise customer's security review.&lt;/strong&gt; Big-co procurement runs an SCA(software composition analysis) tool. AGPL is on their banned-license list, and it is on &lt;em&gt;most&lt;/em&gt; corporate banned lists, precisely because of Section 13. Your deal is now blocked on a license remediation that can't happen overnight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A competitor or a disgruntled user files a complaint.&lt;/strong&gt; Now the choice  is between publishing your crown jewels and writing Astrodienst a check sized by someone who knows you have no leverage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cost of an AGPL dependency isn't zero just because nobody's invoiced&lt;br&gt;
you yet.It's a &lt;strong&gt;contingent liability&lt;/strong&gt; sitting on your balance sheet, and it comes due exactly when you can least afford it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The way out: same accuracy, sane license
&lt;/h2&gt;

&lt;p&gt;For thirty years the trade-off was brutal and unspoken: &lt;strong&gt;the only JPL-accurate ephemeris was AGPL/commercial C.&lt;/strong&gt; The permissive alternatives (&lt;code&gt;astro&lt;/code&gt;,&lt;code&gt;practical-astronomy-rust&lt;/code&gt; on crates.io) are lovely little textbook crates:arcminute-grade, astronomy-only, no astrology layer. So everyone held their nose and took the AGPL, because there was no other accurate option.&lt;/p&gt;

&lt;p&gt;There is now. It's called &lt;strong&gt;XALEN Ephemeris&lt;/strong&gt;, and it's &lt;strong&gt;Apache-2.0.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache-2.0 is the opposite of AGPL in every way that matters here:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;AGPL-3.0 (Swiss)&lt;/th&gt;
&lt;th&gt;Apache-2.0 (XALEN)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Use in closed-source SaaS&lt;/td&gt;
&lt;td&gt;triggers Section 13&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-deployment / commercial fee&lt;/td&gt;
&lt;td&gt;or open everything&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network/copyleft clause&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Patent grant&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;explicit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Obligation&lt;/td&gt;
&lt;td&gt;Publish your source&lt;/td&gt;
&lt;td&gt;Keep the attribution notice&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ship it in a closed-source product, keep the source private, and the only duty is to preserve the license notice. That's the entire deal.&lt;/p&gt;

&lt;h2&gt;
  
  
  And there's no accuracy tax
&lt;/h2&gt;

&lt;p&gt;The catch with "permissive ephemeris" used to be that permissive meant&lt;br&gt;
inaccurate. Not here. XALEN's numbers are reproducible from its own test suite(&lt;code&gt;cargo test --workspace&lt;/code&gt;, 2,199 passing), measured against &lt;strong&gt;JPL Horizons DE440&lt;/strong&gt;, the same reference Swiss reads:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sun:&lt;/strong&gt; 0.21″&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mercury–Saturn:&lt;/strong&gt; ≤ 0.76″, with &lt;strong&gt;zero data files&lt;/strong&gt; (VSOP87A compiled in)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Moon:&lt;/strong&gt; RMS ~2.8″ analytically; sub-arcsecond with the optional DE440 kernel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5,000,000-chart&lt;/strong&gt; diff vs Swiss Ephemeris: &lt;strong&gt;0 charts&lt;/strong&gt; off by more
than 0.1°&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And because it's pure Rust with &lt;strong&gt;zero &lt;code&gt;unsafe&lt;/code&gt; in the computation core&lt;/strong&gt;, no process-global state, and a &lt;code&gt;Send + Sync&lt;/code&gt; engine, Swiss's other two headaches go away too: the &lt;code&gt;.se1&lt;/code&gt; data files you have to ship and the global &lt;code&gt;swe_set_*&lt;/code&gt;state you have to mutex. But honestly? Even if XALEN were &lt;em&gt;only&lt;/em&gt; "Swiss accuracy with a license that doesn't threaten your company," that would be enough to switch.&lt;/p&gt;

&lt;p&gt;XALEN ships a Swiss-compatible shim specifically to make door #3 cheap: a&lt;br&gt;
&lt;code&gt;swe_calc_ut(jd, SE_SUN, ...)&lt;/code&gt; surface with the same &lt;code&gt;xx[0..6]&lt;/code&gt; array semantics already in your code, so migration is closer to search-and-replace than rewrite.&lt;/p&gt;

&lt;p&gt;The AGPL clause has been sitting in your stack this whole time. It didn't go off because nobody looked, not because it's safe. Look now, while looking is cheap.&lt;/p&gt;

&lt;p&gt;→ *&lt;em&gt;github.com/vedika-io/xalen-ephemeris&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Stop shipping a 1990s C library to compute planets. Xalen is the pure-Rust, Apache-2.0 replacement for Swiss Ephemeris.</title>
      <dc:creator>Xalen Technologies</dc:creator>
      <pubDate>Wed, 03 Jun 2026 12:39:10 +0000</pubDate>
      <link>https://dev.to/xalen/stop-shipping-a-1990s-c-library-to-compute-planets-xalen-is-the-pure-rust-apache-20-replacement-1bho</link>
      <guid>https://dev.to/xalen/stop-shipping-a-1990s-c-library-to-compute-planets-xalen-is-the-pure-rust-apache-20-replacement-1bho</guid>
      <description>&lt;h2&gt;
  
  
  Stop shipping a 1990s C library to compute planets. Xalen is the pure-Rust, Apache-2.0 replacement for Swiss Ephemeris.
&lt;/h2&gt;

&lt;p&gt;If your app does astrology, you already know the dependency. Swiss Ephemeris: a C library from the 1990s, a folder of binary &lt;code&gt;.se1&lt;/code&gt; data files you have to ship and locate at runtime, and a license that is either AGPL or you pay for a commercial seat. For 30 years it was the only serious option, so everyone just swallowed the cost.&lt;/p&gt;

&lt;p&gt;That era is over. Xalen Ephemeris is a full planetary engine written in pure Rust, with no &lt;code&gt;unsafe&lt;/code&gt; in the core engine (the only &lt;code&gt;unsafe&lt;/code&gt; lives in the optional FFI, Node and WASM binding crates), released under Apache-2.0. No C toolchain. No data files to ship. No copyleft clause waiting for the day you try to make money. It is built to replace Swiss Ephemeris in production, not to admire it from a distance.&lt;/p&gt;

&lt;p&gt;Python is live on PyPI and the Rust crates are live on crates.io:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Python&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;xalen

&lt;span class="c"&gt;# Rust&lt;/span&gt;
cargo add xalen-ephem xalen-time xalen-ayanamsa xalen-vedic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Node and WASM build straight from the repo. Repo: &lt;a href="https://github.com/vedika-io/xalen-ephemeris" rel="noopener noreferrer"&gt;https://github.com/vedika-io/xalen-ephemeris&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Switching takes one line
&lt;/h2&gt;

&lt;p&gt;Xalen ships a pyswisseph-shaped API on purpose. Migrating an existing codebase is a find-and-replace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# before
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;swisseph&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;swe&lt;/span&gt;
&lt;span class="c1"&gt;# after
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;xalen.swe&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;swe&lt;/span&gt;

&lt;span class="n"&gt;jd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;swe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;julday&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1990&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;10.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;xx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;swe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calc_ut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;swe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SUN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;swe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FLG_SWIEPH&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;swe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FLG_SPEED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# same argument order, same SE_/SEFLG_/SIDM_ constants, same tuple layout
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your function calls do not change. Your data-file directory disappears. Your license problem disappears.&lt;/p&gt;

&lt;h2&gt;
  
  
  Xalen vs Swiss Ephemeris
&lt;/h2&gt;

&lt;p&gt;Line them up and the gap is hard to miss. Swiss Ephemeris is C from the 1990s, shipped as a native library you compile and link, fed by &lt;code&gt;.se1&lt;/code&gt; data files you have to bundle and locate at runtime, under AGPL or a paid commercial license. Xalen is pure Rust with no &lt;code&gt;unsafe&lt;/code&gt; in the core engine, thread-safe, with no native dependency and no data files for the analytical engine (the DE440 kernel is optional), under permissive Apache-2.0. Swiss reaches other languages through third-party wrappers; Xalen targets Rust, Python, C and C++, Node and WASM from one core. On accuracy both track JPL DE, and Xalen matches DE440 to sub-arcsecond on the inner planets with the kernel available for full precision. Swiss gives you positions, houses and ayanamsa and stops there; Xalen ships the entire astrology layer on top, renders charts to SVG, geocodes 130+ cities and localizes into 19 languages. And switching is one line: &lt;code&gt;import xalen.swe as swe&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part nobody else ships
&lt;/h2&gt;

&lt;p&gt;This is where the comparison stops being close. A raw ephemeris, JPL's or Swiss's, hands you coordinates. Then you spend the next two years building the astrology yourself. Xalen ships that layer, for the whole world, in the box:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;India / Vedic (Jyotish).&lt;/strong&gt; Vimshottari and other dashas, 16 divisional charts (vargas), full panchang with tithi, nakshatra, yoga and karana transition times, shadbala, KP, Jaimini, Tajaka annual charts, yogas, doshas, and compatibility. Plus Lal Kitab remedial astrology.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Western.&lt;/strong&gt; Aspects, essential and accidental dignities, 97 Arabic Lots, Hellenistic and Uranian techniques, Cosmobiology, secondary progressions, exact solar and lunar returns by iterative refinement, declination aspects and antiscia, harmonics, and horary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;China.&lt;/strong&gt; BaZi Four Pillars, Zi Wei Dou Shu, Feng Shui Flying Stars, and Qi Men Dun Jia (experimental).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The rest of the world.&lt;/strong&gt; Korean Saju, Japanese Nine Star Ki, Burmese Mahabote, Mayan and Aztec calendars, Tibetan, Persian/Zoroastrian, Egyptian, and Celtic systems. I Ching with all 64 hexagrams and the full 384 line texts. Pythagorean and Chaldean numerology (Life Path, Expression, Soul Urge).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And the astronomy a serious engine needs.&lt;/strong&gt; 50 ayanamsa systems and 23 house systems. A rigorous solar and lunar eclipse engine with Besselian elements and per-observer local circumstances, validated against NASA for 2017 and 2024. 506 built-in fixed stars plus 8,870 compiled-in Hipparcos stars and the full 118,218-star catalog loadable at runtime. Black Moon Lilith (mean and true), Chiron, nodes, and 15 asteroids and TNOs. Velocity and retrograde flags, topocentric positions, and RA/Dec, heliocentric and rectangular output. Real time systems: UT1/TT/TDB, the full leap-second table, and a Stephenson-Morrison-Hohenkerk delta-T spline. SVG chart rendering (North Indian, South Indian, Western wheel) with zero dependencies, 130+ city geocoding, and names in 19 languages.&lt;/p&gt;

&lt;p&gt;Swiss Ephemeris gives you the math and stops. JPL gives you the coordinates and stops. Xalen gives you all of it, from one Apache-2.0 engine, with Rust, Python, Node, WASM and C bindings. A few of these are flagged experimental in the docs, and they are labelled honestly rather than hidden.&lt;/p&gt;

&lt;h2&gt;
  
  
  The accuracy is not a vibe, it is a number
&lt;/h2&gt;

&lt;p&gt;Most libraries ask you to trust them. Xalen hands you the receipts, in two layers. The first is a reproducible 5,000,000-chart consistency sweep: random &lt;code&gt;(date, lat, lon)&lt;/code&gt; charts spanning the years 1500 to 2400, every one diffed against a Swiss Ephemeris (pyswisseph) oracle for every body, the house cusps, and four ayanamsas. The harness is in the repo and it is deterministic, so you can reproduce the entire run yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 validation/oracle_pyswisseph.py &lt;span class="nt"&gt;--n&lt;/span&gt; 5000000 &lt;span class="nt"&gt;--seed&lt;/span&gt; 42 &lt;span class="se"&gt;\&lt;/span&gt;
  | cargo run &lt;span class="nt"&gt;-p&lt;/span&gt; xalen-validation &lt;span class="nt"&gt;--release&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One honest note on that sweep: the oracle is pyswisseph, and without Swiss or JPL data files (&lt;code&gt;.se1&lt;/code&gt; / &lt;code&gt;.bsp&lt;/code&gt;) it falls back to the analytic Moshier theory, so by default it measures analytic-against-analytic agreement. The harness prints exactly which backend it used; point it at the data files for a true Swiss-backed comparison.&lt;/p&gt;

&lt;p&gt;The headline accuracy comes from the second layer: a committed cross-validation against JPL Horizons vectors, run with &lt;code&gt;cargo test&lt;/code&gt;. Against DE440, the Sun lands at 0.21 arcsec and Mercury through Saturn stay under 0.76 arcsec. Uranus and Neptune sit at 1.8 to 2.5 arcsec. The analytical Moon holds an RMS near 2.8 arcsec, and loading the optional DE440 kernel takes the Sun, planets and Moon sub-arcsecond with full-range Pluto. Every figure is per-body and reproducible. The full breakdown is in &lt;code&gt;docs/ACCURACY.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is the point worth sitting with: a pure-Rust engine with zero data files matches the gold-standard NASA DE440 ephemeris to a fraction of an arcsecond on the inner planets, and backs it with a reproducible five-million-chart consistency sweep on top. You do not have to choose between "clean dependency" and "correct."&lt;/p&gt;

&lt;h2&gt;
  
  
  A clean-room engine, not a wrapper
&lt;/h2&gt;

&lt;p&gt;Xalen is an independent, clean-room implementation, not affiliated with Astrodienst. It is built directly from the published theories the whole field relies on: VSOP87, ELP-2000/82, IAU 2006 precession with 2000B nutation, and the Stephenson, Morrison and Hohenkerk delta-T model, with JPL DE440 as an optional high-precision kernel. It is cross-checked against Swiss Ephemeris because that is the honest way to prove a replacement, not because a single line of it is borrowed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it stands today
&lt;/h2&gt;

&lt;p&gt;This is a launch, and the engine is ready for real work.&lt;/p&gt;

&lt;p&gt;If you have ever fought the Swiss Ephemeris C build, hunted for a missing &lt;code&gt;.se1&lt;/code&gt; file in production, or had a licensing conversation you did not enjoy, Xalen is the exit. Star it, fork it, and put it head to head with whatever you trust:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/vedika-io/xalen-ephemeris" rel="noopener noreferrer"&gt;https://github.com/vedika-io/xalen-ephemeris&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try to break it. Open an issue with a chart Xalen gets wrong against your reference. Out of five million, the next interesting failure is the one you find.&lt;/p&gt;

&lt;p&gt;Xalen is a computation engine. Any astrological interpretation built on top of it is for informational and cultural purposes, not professional advice.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>astronomy</category>
    </item>
  </channel>
</rss>
